Serious-Engine/Sources/SeriousSam/MainWindow.cpp

368 lines
9.5 KiB
C++
Raw Normal View History

2016-03-11 14:57:17 +01:00
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
#include "SeriousSam/StdH.h"
2016-03-11 14:57:17 +01:00
#include "MainWindow.h"
#include "resource.h"
// !!! FIXME : Make a clean abstraction, remove these #ifdefs.
#ifdef PLATFORM_UNIX
#include "SDL.h"
#endif
2016-03-11 14:57:17 +01:00
BOOL _bWindowChanging = FALSE; // ignores window messages while this is set
HWND _hwndMain = NULL;
static char achWindowTitle[256]; // current window title
2016-03-11 14:57:17 +01:00
// for window reposition function
static PIX _pixLastSizeI, _pixLastSizeJ;
#ifdef PLATFORM_WIN32
static HBITMAP _hbmSplash = NULL;
static BITMAP _bmSplash;
2016-03-11 14:57:17 +01:00
// window procedure active while window changes are occuring
LRESULT WindowProc_WindowChanging( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message ) {
case WM_PAINT: {
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
} break;
case WM_ERASEBKGND: {
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
FillRect(ps.hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
HDC hdcMem = CreateCompatibleDC(ps.hdc);
SelectObject(hdcMem, _hbmSplash);
BitBlt(ps.hdc, 0, 0, _bmSplash.bmWidth, _bmSplash.bmHeight, hdcMem, 0, 0, SRCCOPY);
// StretchBlt(ps.hdc, 0, 0, rect.right, rect.bottom,
// hdcMem, 0,0, _bmSplash.bmWidth, _bmSplash.bmHeight, SRCCOPY);
EndPaint(hWnd, &ps);
return 1;
} break;
case WM_CLOSE:
return 0;
break;
}
return DefWindowProcA(hWnd, message, wParam, lParam);
}
// window procedure active normally
LRESULT WindowProc_Normal( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message ) {
// system commands
case WM_SYSCOMMAND: {
switch( wParam & ~0x0F) {
// window resizing messages
case SC_MINIMIZE:
case SC_RESTORE:
case SC_MAXIMIZE:
// relay to application
PostMessage(NULL, message, wParam & ~0x0F, lParam);
// do not allow automatic resizing
return 0;
break;
// prevent screen saver and monitor power down
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
} break;
// when close box is clicked
case WM_CLOSE:
// relay to application
PostMessage(NULL, message, wParam, lParam);
// do not pass to default wndproc
return 0;
// some standard focus loose/gain messages
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_CANCELMODE:
case WM_KILLFOCUS:
case WM_ACTIVATEAPP:
// relay to application
PostMessage(NULL, message, wParam, lParam);
// pass to default wndproc
break;
}
// if we get to here, we pass the message to default procedure
return DefWindowProcA(hWnd, message, wParam, lParam);
}
// main window procedure
LRESULT CALLBACK WindowProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
// dispatch to proper window procedure
if(_bWindowChanging) {
return WindowProc_WindowChanging(hWnd, message, wParam, lParam);
} else {
return WindowProc_Normal(hWnd, message, wParam, lParam);
}
}
#endif
2016-03-11 14:57:17 +01:00
// init/end main window management
void MainWindow_Init(void)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
// register the window class
WNDCLASSEXA wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = _hInstance;
wc.hIcon = LoadIconA( _hInstance, (LPCSTR)IDR_MAINFRAME );
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = APPLICATION_NAME;
wc.lpszClassName = APPLICATION_NAME;
wc.hIconSm = NULL;
if (0 == RegisterClassExA(&wc)) {
DWORD dwError = GetLastError();
CTString strErrorMessage(TRANS("Cannot open main window!"));
CTString strError;
strError.PrintF("%s Error %d", strErrorMessage, dwError);
FatalError(strError);
}
// load bitmaps
_hbmSplash = LoadBitmapA(_hInstance, (char*)IDB_SPLASH);
ASSERT(_hbmSplash!=NULL);
GetObject(_hbmSplash, sizeof(BITMAP), (LPSTR) &_bmSplash);
// here was loading and setting of no-windows-mouse-cursor
#else
STUBBED("load window icon");
#endif
2016-03-11 14:57:17 +01:00
}
void MainWindow_End(void)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
DeleteObject(_hbmSplash);
#else
STUBBED("");
#endif
2016-03-11 14:57:17 +01:00
}
// close the main application window
void CloseMainWindow(void)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
// if window exists
if( _hwndMain!=NULL) {
// destroy it
DestroyWindow(_hwndMain);
_hwndMain = NULL;
}
#else
_hwndMain = NULL;
#endif
2016-03-11 14:57:17 +01:00
}
#ifdef PLATFORM_UNIX
static void CreateSDLWindow(PIX pixSizeI, PIX pixSizeJ,
const char *title, const char *icon,
Uint32 flags)
{
flags |= SDL_OPENGL;
SDL_WM_SetCaption(title, icon);
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
// ShowCursor(0) and input grabbing need to be done here to prevent a
// Voodoo 3 bug. Was this ever fixed?
SDL_ShowCursor(0);
SDL_WM_GrabInput(SDL_GRAB_ON);
int color_depth[] = {32, 24, 16, 15, -1};
int i;
if (_pGfx->gl_iCurrentDepth != 0)
{
color_depth[0] = _pGfx->gl_iCurrentDepth;
color_depth[1] = -1;
} // if
for (i = 0; color_depth[i] > 0; i++)
{
int bits = (color_depth[i] >= 24) ? 8 : 5;
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, bits);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, bits);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, bits);
if (SDL_SetVideoMode(pixSizeI, pixSizeJ, color_depth[i], flags) != NULL)
break;
CPrintF("SDL_SetVideoMode() failed at %d-bit color! Reason: %s\n", color_depth[i], SDL_GetError());
} // for
SDL_WM_GrabInput(SDL_GRAB_OFF);
if (color_depth[i] > 0)
_pGfx->gl_iCurrentDepth = color_depth[i];
else
{
SDL_Quit();
FatalError("Failed to create GL context.\n");
} // else
_hwndMain = (void *) 0x0001;
SE_UpdateWindowHandle( _hwndMain);
} // CreateSDLWindow
#endif
2016-03-11 14:57:17 +01:00
void ResetMainWindowNormal(void)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
ShowWindow( _hwndMain, SW_HIDE);
// add edges and title bar to window size so client area would have size that we requested
RECT rWindow, rClient;
GetClientRect( _hwndMain, &rClient);
GetWindowRect( _hwndMain, &rWindow);
const PIX pixWidth = _pixLastSizeI + (rWindow.right-rWindow.left) - (rClient.right-rClient.left);
const PIX pixHeight = _pixLastSizeJ + (rWindow.bottom-rWindow.top) - (rClient.bottom-rClient.top);
const PIX pixPosX = (::GetSystemMetrics(SM_CXSCREEN) - pixWidth ) /2;
const PIX pixPosY = (::GetSystemMetrics(SM_CYSCREEN) - pixHeight) /2;
// set new window size and show it
SetWindowPos( _hwndMain, NULL, pixPosX,pixPosY, pixWidth,pixHeight, SWP_NOZORDER);
ShowWindow( _hwndMain, SW_SHOW);
#endif
2016-03-11 14:57:17 +01:00
}
// open the main application window for windowed mode
void OpenMainWindowNormal( PIX pixSizeI, PIX pixSizeJ)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
ASSERT(_hwndMain==NULL);
// create a window, invisible initially
_hwndMain = CreateWindowExA(
WS_EX_APPWINDOW,
APPLICATION_NAME,
"", // title
WS_OVERLAPPED|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU,
10,10,
100,100, // window size
NULL,
NULL,
_hInstance,
NULL);
// didn't make it?
if( _hwndMain==NULL) FatalError(TRANS("Cannot open main window!"));
SE_UpdateWindowHandle( _hwndMain);
// set window title
sprintf( achWindowTitle, TRANS("Serious Sam (Window %dx%d)"), pixSizeI, pixSizeJ);
SetWindowTextA( _hwndMain, achWindowTitle);
_pixLastSizeI = pixSizeI;
_pixLastSizeJ = pixSizeJ;
ResetMainWindowNormal();
#else
_pixLastSizeI = pixSizeI;
_pixLastSizeJ = pixSizeJ;
// set window title
sprintf( achWindowTitle, TRANS("Serious Sam (Window %dx%d)"), pixSizeI, pixSizeJ);
CreateSDLWindow(pixSizeI, pixSizeJ, achWindowTitle, "ssam", 0);
#endif
2016-03-11 14:57:17 +01:00
}
// open the main application window for fullscreen mode
void OpenMainWindowFullScreen( PIX pixSizeI, PIX pixSizeJ)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
ASSERT( _hwndMain==NULL);
// create a window, invisible initially
_hwndMain = CreateWindowExA(
WS_EX_TOPMOST | WS_EX_APPWINDOW,
APPLICATION_NAME,
"", // title
WS_POPUP,
0,0,
pixSizeI, pixSizeJ, // window size
NULL,
NULL,
_hInstance,
NULL);
// didn't make it?
if( _hwndMain==NULL) FatalError(TRANS("Cannot open main window!"));
SE_UpdateWindowHandle( _hwndMain);
// set window title and show it
sprintf( achWindowTitle, TRANS("Serious Sam (FullScreen %dx%d)"), pixSizeI, pixSizeJ);
SetWindowTextA( _hwndMain, achWindowTitle);
ShowWindow( _hwndMain, SW_SHOWNORMAL);
#else
// set window title
sprintf( achWindowTitle, TRANS("Serious Sam (FullScreen %dx%d)"), pixSizeI, pixSizeJ);
CreateSDLWindow(pixSizeI, pixSizeJ, achWindowTitle, "ssam", SDL_FULLSCREEN);
#endif
2016-03-11 14:57:17 +01:00
}
// open the main application window invisible
void OpenMainWindowInvisible(void)
{
#ifdef PLATFORM_WIN32
2016-03-11 14:57:17 +01:00
ASSERT(_hwndMain==NULL);
// create a window, invisible initially
_hwndMain = CreateWindowExA(
WS_EX_APPWINDOW,
APPLICATION_NAME,
"", // title
WS_POPUP,
0,0,
10, 10, // window size
NULL,
NULL,
_hInstance,
NULL);
// didn't make it?
if( _hwndMain==NULL) {
DWORD dwError = GetLastError();
CTString strErrorMessage(TRANS("Cannot open main window!"));
CTString strError;
strError.PrintF("%s Error %d", strErrorMessage, dwError);
FatalError(strError);
}
SE_UpdateWindowHandle( _hwndMain);
// set window title
sprintf( achWindowTitle, "Serious Sam");
SetWindowTextA( _hwndMain, achWindowTitle);
#else
STUBBED("Need SDL invisible window or something");
#endif
2016-03-11 14:57:17 +01:00
}