jpeg splash images
This commit is contained in:
parent
1de9cc165b
commit
5fea6fffd7
|
|
@ -3,7 +3,7 @@
|
|||
#define BUILD_DIRECTORY $[and $[HAVE_P3D_PLUGIN],$[HAVE_TINYXML],$[HAVE_OPENSSL],$[HAVE_ZLIB]]
|
||||
|
||||
#begin lib_target
|
||||
#define USE_PACKAGES tinyxml openssl zlib
|
||||
#define USE_PACKAGES tinyxml openssl zlib jpeg
|
||||
#define TARGET p3d_plugin
|
||||
#define LIB_PREFIX
|
||||
|
||||
|
|
|
|||
|
|
@ -98,13 +98,6 @@ set_fparams(const P3DFileParams &fparams) {
|
|||
_got_fparams = true;
|
||||
_fparams = fparams;
|
||||
|
||||
// Maybe create the splash window.
|
||||
if (!_instance_window_opened && _got_wparams) {
|
||||
if (_splash_window == NULL) {
|
||||
_splash_window = new SplashWindowType(this);
|
||||
}
|
||||
}
|
||||
|
||||
// This also sets up some internal data based on the contents of the
|
||||
// above file and the associated tokens.
|
||||
|
||||
|
|
@ -115,6 +108,21 @@ set_fparams(const P3DFileParams &fparams) {
|
|||
_session_key = strm.str();
|
||||
|
||||
_python_version = "python24";
|
||||
|
||||
|
||||
// Maybe create the splash window.
|
||||
if (!_instance_window_opened && _got_wparams) {
|
||||
if (_splash_window == NULL) {
|
||||
_splash_window = new SplashWindowType(this);
|
||||
// _splash_window->set_image_filename("c:/Documents and Settings/drose/Desktop/pandalogo.jpg");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
string splash_image_url = _fparams.lookup_token("splash_img");
|
||||
if (!splash_image_url.is_empty()) {
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -133,6 +141,7 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||
if (!_instance_window_opened && _got_fparams) {
|
||||
if (_splash_window == NULL) {
|
||||
_splash_window = new SplashWindowType(this);
|
||||
// _splash_window->set_image_filename("c:/Documents and Settings/drose/Desktop/pandalogo.jpg");
|
||||
} else {
|
||||
_splash_window->set_wparams(_wparams);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,16 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||
_wparams = wparams;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::set_image_filename
|
||||
// Access: Public, Virtual
|
||||
// Description: Specifies the name of a JPEG image file that is
|
||||
// displayed in the center of the splash window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSplashWindow::
|
||||
set_image_filename(const string &image_filename) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::set_install_label
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||
inline const P3DWindowParams &get_wparams() const;
|
||||
|
||||
virtual void set_image_filename(const string &image_filename);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,31 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
|
||||
// Stuff to use libjpeg.
|
||||
extern "C" {
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
}
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
struct my_error_mgr {
|
||||
struct jpeg_error_mgr pub;
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
typedef struct my_error_mgr *my_error_ptr;
|
||||
|
||||
METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
|
||||
// cinfo->err really points to a my_error_mgr struct, so coerce pointer
|
||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
||||
// Return control to the setjmp point
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::Constructor
|
||||
// Access: Public
|
||||
|
|
@ -28,12 +53,14 @@ P3DWinSplashWindow(P3DInstance *inst) :
|
|||
_thread = NULL;
|
||||
_thread_id = 0;
|
||||
_hwnd = NULL;
|
||||
_bitmap = NULL;
|
||||
_progress_bar = NULL;
|
||||
_text_label = NULL;
|
||||
_thread_running = false;
|
||||
_got_install = false;
|
||||
_install_progress = 0.0;
|
||||
_image_filename_changed = false;
|
||||
_install_label_changed = false;
|
||||
_install_progress = 0.0;
|
||||
|
||||
INIT_LOCK(_install_lock);
|
||||
|
||||
|
|
@ -52,6 +79,31 @@ P3DWinSplashWindow::
|
|||
DESTROY_LOCK(_install_lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::set_image_filename
|
||||
// Access: Public, Virtual
|
||||
// Description: Specifies the name of a JPEG image file that is
|
||||
// displayed in the center of the splash window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
set_image_filename(const string &image_filename) {
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
if (_image_filename != image_filename) {
|
||||
_image_filename = image_filename;
|
||||
_image_filename_changed = true;
|
||||
}
|
||||
RELEASE_LOCK(_install_lock);
|
||||
|
||||
// Post a silly message to spin the message loop.
|
||||
PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||
|
||||
if (!_thread_running && _thread_continue) {
|
||||
// The user must have closed the window. Let's shut down the
|
||||
// instance, too.
|
||||
_inst->request_stop();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::set_install_label
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -156,6 +208,10 @@ thread_run() {
|
|||
if (_got_install) {
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
double install_progress = _install_progress;
|
||||
if (_image_filename_changed) {
|
||||
update_image_filename(_image_filename);
|
||||
}
|
||||
_image_filename_changed = false;
|
||||
if (_install_label_changed && _progress_bar != NULL) {
|
||||
update_install_label(_install_label);
|
||||
}
|
||||
|
|
@ -213,7 +269,7 @@ make_window() {
|
|||
static bool registered_class = false;
|
||||
if (!registered_class) {
|
||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||
wc.lpfnWndProc = window_proc;
|
||||
wc.lpfnWndProc = st_window_proc;
|
||||
wc.hInstance = application;
|
||||
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
wc.lpszClassName = "panda3d_splash";
|
||||
|
|
@ -241,7 +297,7 @@ make_window() {
|
|||
if (_wparams.get_window_type() == P3D_WT_embedded) {
|
||||
// Create an embedded window.
|
||||
DWORD window_style =
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
|
||||
HWND parent_hwnd = _wparams.get_parent_window()._hwnd;
|
||||
|
||||
|
|
@ -270,9 +326,9 @@ make_window() {
|
|||
nout << "Could not create toplevel window!\n";
|
||||
return;
|
||||
}
|
||||
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
}
|
||||
SetWindowLongPtr(_hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -308,18 +364,19 @@ make_progress_bar() {
|
|||
int bar_width = min((int)(width * 0.6), 400);
|
||||
int bar_height = min((int)(height * 0.1), 24);
|
||||
int bar_x = (width - bar_width) / 2;
|
||||
int bar_y = (height - bar_height) / 2;
|
||||
int bar_y = (height - bar_height * 2);
|
||||
|
||||
_progress_bar =
|
||||
CreateWindowEx(0, PROGRESS_CLASS, "", window_style,
|
||||
bar_x, bar_y, bar_width, bar_height,
|
||||
_hwnd, NULL, application, 0);
|
||||
CreateWindowEx(0, PROGRESS_CLASS, "", window_style,
|
||||
bar_x, bar_y, bar_width, bar_height,
|
||||
_hwnd, NULL, application, 0);
|
||||
SendMessage(_progress_bar, PBM_SETPOS, (int)(install_progress * 100.0), 0);
|
||||
ShowWindow(_progress_bar, SW_SHOWNORMAL);
|
||||
|
||||
update_install_label(install_label);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::update_install_label
|
||||
// Access: Private
|
||||
|
|
@ -361,7 +418,7 @@ update_install_label(const string &install_label) {
|
|||
int height = rect.bottom - rect.top;
|
||||
|
||||
int bar_height = min((int)(height * 0.1), 24);
|
||||
int bar_y = (height - bar_height) / 2;
|
||||
int bar_y = (height - bar_height * 2);
|
||||
|
||||
int text_width = text_size.cx;
|
||||
int text_height = text_size.cy;
|
||||
|
|
@ -374,6 +431,107 @@ update_install_label(const string &install_label) {
|
|||
ShowWindow(_text_label, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::update_image_filename
|
||||
// Access: Private
|
||||
// Description: Loads the splash image, converts to to BITMAP form,
|
||||
// and stores it in _bitmap. Runs only in the
|
||||
// sub-thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
update_image_filename(const string &image_filename) {
|
||||
// Clear the old image.
|
||||
if (_bitmap != NULL) {
|
||||
DeleteObject(_bitmap);
|
||||
_bitmap = NULL;
|
||||
}
|
||||
|
||||
// Since we'll be displaying a new image, we need to refresh the
|
||||
// window.
|
||||
InvalidateRect(_hwnd, NULL, TRUE);
|
||||
|
||||
FILE *fp = fopen(image_filename.c_str(), "rb");
|
||||
if (fp == NULL) {
|
||||
nout << "Couldn't open splash file image: " << image_filename << "\n"
|
||||
<< flush;
|
||||
return;
|
||||
}
|
||||
|
||||
// We set up the normal JPEG error routines, then override error_exit.
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
|
||||
struct my_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
// Establish the setjmp return context for my_error_exit to use
|
||||
if (setjmp(jerr.setjmp_buffer)) {
|
||||
// If we get here, the JPEG code has signaled an error.
|
||||
nout << "JPEG error decoding " << image_filename << "\n"
|
||||
<< flush;
|
||||
|
||||
// We need to clean up the JPEG object, close the input file, and return.
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we can initialize the JPEG decompression object. */
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, fp);
|
||||
|
||||
jpeg_read_header(&cinfo, true);
|
||||
|
||||
cinfo.scale_num = 1;
|
||||
cinfo.scale_denom = 1;
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
_bitmap_width = cinfo.output_width;
|
||||
_bitmap_height = cinfo.output_height;
|
||||
|
||||
int row_stride = _bitmap_width * cinfo.output_components;
|
||||
// We have to pad row_stride out to DWORD alignment.
|
||||
row_stride = 4 * ((row_stride + 3) / 4);
|
||||
|
||||
size_t buffer_size = _bitmap_height * row_stride;
|
||||
JSAMPLE *buffer = new JSAMPLE[buffer_size];
|
||||
JSAMPLE *buffer_end = buffer + buffer_size;
|
||||
|
||||
JSAMPLE *rowptr = buffer;
|
||||
while (cinfo.output_scanline < cinfo.output_height) {
|
||||
assert(rowptr + row_stride <= buffer_end);
|
||||
jpeg_read_scanlines(&cinfo, &rowptr, 1);
|
||||
rowptr += row_stride;
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
// Now load the image.
|
||||
BITMAPINFOHEADER bmih;
|
||||
bmih.biSize = sizeof(bmih);
|
||||
bmih.biWidth = _bitmap_width;
|
||||
bmih.biHeight = -_bitmap_height;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = 8 * cinfo.output_components;
|
||||
bmih.biCompression = BI_RGB;
|
||||
bmih.biSizeImage = 0;
|
||||
bmih.biXPelsPerMeter = 0;
|
||||
bmih.biYPelsPerMeter = 0;
|
||||
bmih.biClrUsed = 0;
|
||||
bmih.biClrImportant = 0;
|
||||
|
||||
BITMAPINFO bmi;
|
||||
memcpy(&bmi, &bmih, sizeof(bmih));
|
||||
|
||||
HDC dc = GetDC(_hwnd);
|
||||
_bitmap = CreateDIBitmap(dc, &bmih, CBM_INIT, buffer, &bmi, 0);
|
||||
ReleaseDC(_hwnd, dc);
|
||||
|
||||
nout << "Loaded splash file image: " << image_filename << "\n"
|
||||
<< flush;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::close_window
|
||||
// Access: Private
|
||||
|
|
@ -381,16 +539,21 @@ update_install_label(const string &install_label) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
close_window() {
|
||||
if (_hwnd) {
|
||||
if (_hwnd != NULL) {
|
||||
ShowWindow(_hwnd, SW_HIDE);
|
||||
CloseWindow(_hwnd);
|
||||
_hwnd = NULL;
|
||||
}
|
||||
|
||||
if (_bitmap != NULL) {
|
||||
DeleteObject(_bitmap);
|
||||
_bitmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::window_proc
|
||||
// Access: Private, Static
|
||||
// Access: Private
|
||||
// Description: The windows event-processing handler.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG P3DWinSplashWindow::
|
||||
|
|
@ -400,6 +563,62 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
nout << "WM_PAINT, _bitmap = " << _bitmap << "\n";
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC dc = BeginPaint(hwnd, &ps);
|
||||
if (_bitmap != NULL) {
|
||||
// Paint the background splash image.
|
||||
HDC mem_dc = CreateCompatibleDC(dc);
|
||||
SelectObject(mem_dc, _bitmap);
|
||||
|
||||
// Determine the relative size of bitmap and window.
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
int win_width = rect.right - rect.left;
|
||||
int win_height = rect.bottom - rect.top;
|
||||
int bm_width = _bitmap_width;
|
||||
int bm_height = _bitmap_height;
|
||||
|
||||
int win_cx = win_width / 2;
|
||||
int win_cy = win_height / 2;
|
||||
|
||||
if (bm_width <= win_width && bm_height <= win_height) {
|
||||
// The bitmap fits within the window; center it.
|
||||
|
||||
// This is the top-left corner of the bitmap in window coordinates.
|
||||
int p_x = win_cx - bm_width / 2;
|
||||
int p_y = win_cy - bm_height / 2;
|
||||
|
||||
BitBlt(dc, p_x, p_y, bm_width, bm_height,
|
||||
mem_dc, 0, 0, SRCCOPY);
|
||||
|
||||
} else {
|
||||
// The bitmap is larger than the window; scale it down.
|
||||
double x_scale = (double)win_width / (double)bm_width;
|
||||
double y_scale = (double)win_height / (double)bm_height;
|
||||
double scale = min(x_scale, y_scale);
|
||||
int sc_width = (int)(bm_width * scale);
|
||||
int sc_height = (int)(bm_height * scale);
|
||||
|
||||
int p_x = win_cx - sc_width / 2;
|
||||
int p_y = win_cy - sc_height / 2;
|
||||
StretchBlt(dc, p_x, p_y, sc_width, sc_height,
|
||||
mem_dc, 0, 0, bm_width, bm_height, SRCCOPY);
|
||||
}
|
||||
|
||||
SelectObject(mem_dc, NULL);
|
||||
DeleteDC(mem_dc);
|
||||
}
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_DRAWITEM:
|
||||
// Draw a text label placed within the window.
|
||||
{
|
||||
|
|
@ -422,5 +641,20 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DWinSplashWindow::st_window_proc
|
||||
// Access: Private, Static
|
||||
// Description: The windows event-processing handler, static version.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG P3DWinSplashWindow::
|
||||
st_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
LONG_PTR self = GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
if (self == NULL) {
|
||||
// We haven't assigned the pointer yet.
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
return ((P3DWinSplashWindow *)self)->window_proc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ public:
|
|||
P3DWinSplashWindow(P3DInstance *inst);
|
||||
virtual ~P3DWinSplashWindow();
|
||||
|
||||
virtual void set_image_filename(const string &image_filename);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
|
||||
|
|
@ -49,12 +50,16 @@ private:
|
|||
void make_window();
|
||||
void make_progress_bar();
|
||||
void update_install_label(const string &install_label);
|
||||
void update_image_filename(const string &image_filename);
|
||||
void close_window();
|
||||
|
||||
static LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
static LONG WINAPI st_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
private:
|
||||
bool _got_install;
|
||||
bool _image_filename_changed;
|
||||
string _image_filename;
|
||||
bool _install_label_changed;
|
||||
string _install_label;
|
||||
double _install_progress;
|
||||
|
|
@ -67,6 +72,8 @@ private:
|
|||
HANDLE _thread;
|
||||
DWORD _thread_id;
|
||||
HWND _hwnd;
|
||||
HBITMAP _bitmap;
|
||||
int _bitmap_width, _bitmap_height;
|
||||
HWND _progress_bar;
|
||||
HWND _text_label;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue