mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-26 15:44:51 +01:00
24cb244d43
This was a _ton_ of changes, made 15 years ago, so there are probably some problems to work out still. Among others: Engine/Base/Stream.* was mostly abandoned and will need to be re-ported. Still, this is a pretty good start, and probably holds a world record for lines of changes or something. :)
368 lines
9.5 KiB
C++
368 lines
9.5 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
|
|
|
#include "SeriousSam/StdH.h"
|
|
#include "MainWindow.h"
|
|
#include "resource.h"
|
|
|
|
// !!! FIXME : Make a clean abstraction, remove these #ifdefs.
|
|
#ifdef PLATFORM_UNIX
|
|
#include "SDL.h"
|
|
#endif
|
|
|
|
BOOL _bWindowChanging = FALSE; // ignores window messages while this is set
|
|
HWND _hwndMain = NULL;
|
|
|
|
static char achWindowTitle[256]; // current window title
|
|
|
|
// for window reposition function
|
|
static PIX _pixLastSizeI, _pixLastSizeJ;
|
|
|
|
|
|
#ifdef PLATFORM_WIN32
|
|
static HBITMAP _hbmSplash = NULL;
|
|
static BITMAP _bmSplash;
|
|
|
|
// 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
|
|
|
|
// init/end main window management
|
|
void MainWindow_Init(void)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
// 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
|
|
}
|
|
|
|
|
|
void MainWindow_End(void)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
DeleteObject(_hbmSplash);
|
|
#else
|
|
STUBBED("");
|
|
#endif
|
|
}
|
|
|
|
|
|
// close the main application window
|
|
void CloseMainWindow(void)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
// if window exists
|
|
if( _hwndMain!=NULL) {
|
|
// destroy it
|
|
DestroyWindow(_hwndMain);
|
|
_hwndMain = NULL;
|
|
}
|
|
#else
|
|
_hwndMain = NULL;
|
|
#endif
|
|
}
|
|
|
|
#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
|
|
|
|
|
|
void ResetMainWindowNormal(void)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
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
|
|
}
|
|
|
|
|
|
// open the main application window for windowed mode
|
|
void OpenMainWindowNormal( PIX pixSizeI, PIX pixSizeJ)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
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
|
|
}
|
|
|
|
|
|
// open the main application window for fullscreen mode
|
|
void OpenMainWindowFullScreen( PIX pixSizeI, PIX pixSizeJ)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
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
|
|
}
|
|
|
|
|
|
// open the main application window invisible
|
|
void OpenMainWindowInvisible(void)
|
|
{
|
|
#ifdef PLATFORM_WIN32
|
|
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
|
|
}
|
|
|