scummvm/sword2/driver/rdwin.cpp
Torbjörn Andersson fcc904a813 FadeServer() is now called from ServiceWindows(), thus eliminating the need
for the making it a timer handler. This should eliminate the occasional
glitches I've been seeing with fades not being completed.

I'm also hoping that it will fix the problem where the game would sometimes
hang when moving between rooms. I know that at least once when I had that
happen to me the game was busy-waiting for the palette to fade.

At the very least, it's one place less to worry about thread-safety in.

svn-id: r9854
2003-08-25 06:13:28 +00:00

624 lines
12 KiB
C++

/* Copyright (C) 1994-2003 Revolution Software Ltd
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*/
#define WIN32_LEAN_AND_MEAN
//#include <windows.h>
//#include <windowsx.h>
#include <stdio.h>
#include "common/stdafx.h"
#include "common/engine.h"
#include "driver96.h"
#include "_mouse.h"
#include "keyboard.h"
#include "rdwin.h"
#include "d_draw.h"
#include "palette.h"
#include "render.h"
#include "menu.h"
#include "d_sound.h"
#include "../sword2.h"
#define MENUDEEP 40 // Temporary, until menu.h is written!
//static BOOL bMouseVisible = FALSE;
//static BOOL controlKey = FALSE;
//static BOOL altKey = FALSE;
//static BOOL wasScreenSaverActive = FALSE;
//static BOOL myAppClosed = FALSE;
static BOOL controlQDisabled = FALSE;
//static uint8 gameName[80];
//BOOL gotTheFocus = FALSE;
//assume we always have focus for the time being - khalek
BOOL gotTheFocus = TRUE;
//HWND hwnd;
//RECT rcWindow;
//-----------------------------------------------------------------------------
void Zdebug(const char *format,...) {
#ifdef __PALM_OS__
char buf[256]; // 1024 is too big overflow the stack
#else
char buf[1024];
#endif
va_list va;
va_start(va, format);
vsprintf(buf, format, va);
va_end(va);
#ifdef __GP32__ //ph0x FIXME: implement fprint?
printf("ZDEBUG: %s\n", buf);
#else
fprintf(stderr, "ZDEBUG: %s!\n", buf);
#endif
#if defined( USE_WINDBG )
strcat(buf, "\n");
#if defined( _WIN32_WCE )
TCHAR buf_unicode[1024];
MultiByteToWideChar(CP_ACP, 0, buf, strlen(buf) + 1, buf_unicode, sizeof(buf_unicode));
OutputDebugString(buf_unicode);
#else
OutputDebugString(buf);
#endif
#endif
}
/*
void Zdebug(char *format,...) //Tony's special debug logging file March96
{
warning("stub Zdebug");
// Write a printf type string to a debug file
va_list arg_ptr; // Variable argument pointer
FILE * debug_filep=0; // Debug file pointer
static int first_debug = 1; // Flag for first time this is used
va_start(arg_ptr,format);
if (first_debug) //First time round delete any previous debug file
{
unlink("debug.txt");
first_debug = 0;
}
debug_filep = fopen("debug.txt","a+t");
if (debug_filep != NULL) // if it could be opened
{
vfprintf(debug_filep, format, arg_ptr);
fprintf(debug_filep,"\n");
fclose(debug_filep);
}
}
*/
//-----------------------------------------------------------------------------
/*
void Message(LPSTR fmt, ...)
{
char buff[256];
va_list va;
va_start(va, fmt);
//
// format message with header
//
lstrcpy( buff, "DRIVER96:" );
wvsprintf( &buff[lstrlen(buff)], fmt, va );
lstrcat( buff, "\r\n" );
//
// To the debugger
//
OutputDebugString( buff );
}
*/
//-----------------------------------------------------------------------------
// OSystem Event Handler. Full of cross platform goodness and 99% fat free!
//-----------------------------------------------------------------------------
void Sword2State::parseEvents() {
OSystem::Event event;
while (_system->poll_event(&event)) {
switch(event.event_code) {
case OSystem::EVENT_KEYDOWN:
if (event.kbd.flags==OSystem::KBD_CTRL) {
if (event.kbd.keycode == 'w')
GrabScreenShot();
}
WriteKey(event.kbd.ascii);
break;
case OSystem::EVENT_MOUSEMOVE:
mousex = event.mouse.x;
mousey = event.mouse.y - MENUDEEP;
break;
case OSystem::EVENT_LBUTTONDOWN:
LogMouseEvent(RD_LEFTBUTTONDOWN);
break;
case OSystem::EVENT_RBUTTONDOWN:
LogMouseEvent(RD_RIGHTBUTTONDOWN);
break;
case OSystem::EVENT_LBUTTONUP:
LogMouseEvent(RD_LEFTBUTTONUP);
break;
case OSystem::EVENT_RBUTTONUP:
LogMouseEvent(RD_RIGHTBUTTONUP);
break;
case OSystem::EVENT_QUIT:
Close_game();
CloseAppWindow();
break;
default:
break;
}
}
}
//-----------------------------------------------------------------------------
// Windows Message Handler. All keyboard and mouse input is handled here.
//-----------------------------------------------------------------------------
/*
long FAR PASCAL WindowsMessageHandler(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_TIMER:
switch (wParam)
{
case 25:
FadeServer();
return(0);
case 1:
FxServer();
return(0);
}
break;
case WM_CLOSE:
Zdebug("WM_CLOSE");
break;
case WM_SIZE:
case WM_MOVE:
if (IsIconic(hwnd))
{
Message("minimising");
// PauseGame();
}
if (bFullScreen)
{
SetRect(&rcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
}
else
{
GetClientRect(hwnd, &rcWindow);
ClientToScreen(hwnd, (LPPOINT)&rcWindow);
ClientToScreen(hwnd, (LPPOINT)&rcWindow+1);
}
Message("WINDOW RECT: [%d,%d,%d,%d]", rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);
if (bFullScreen)
{
SetCapture(hwnd);
}
else
{
ReleaseCapture();
}
// SetCursor(NULL);
// ShowCursor(FALSE);
break;
case WM_ACTIVATEAPP:
gotTheFocus = wParam;
if (gotTheFocus)
{
Message("Got the focus");
bMouseVisible = FALSE;
Message("Mouse invisible");
ShowCursor(FALSE);
}
else
{
if (bMouseVisible == FALSE)
ShowCursor(TRUE);
Message("Lost the focus");
bMouseVisible = TRUE;
Message("Mouse visible");
}
break;
case WM_SYSKEYUP:
switch( wParam )
{
// int32 rv;
// handle ALT+ENTER (fullscreen)
case VK_RETURN:
break;
}
break;
case WM_DISPLAYCHANGE:
break;
case WM_CREATE:
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE , 0 , &wasScreenSaverActive , 0);
if (wasScreenSaverActive)
{
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE , FALSE , 0 , 0 );
}
break;
case WM_QUERYNEWPALETTE:
//
// we are getting the palette focus, select our palette
//
if (!bFullScreen && lpPalette && lpPrimarySurface)
{
int32 hr;
hr = IDirectDrawSurface_BS2_SetPalette(lpPrimarySurface, lpPalette);
if (hr == DDERR_SURFACELOST)
{
IDirectDrawSurface_Restore(lpPrimarySurface);
hr= IDirectDrawSurface_BS2_SetPalette(lpPrimarySurface, lpPalette);
if(hr == DDERR_SURFACELOST)
{
Message("Failed to restore palette after second try");
}
}
//
// Restore normal title if palette is ours
//
if(hr == DD_OK)
{
SetWindowText(hwnd, gameName);
}
}
break;
case WM_PALETTECHANGED:
//
// if another app changed the palette we dont have full control
// of the palette. NOTE this only applies for FoxBear in a window
// when we are fullscreen we get all the palette all of the time.
//
if ((HWND)wParam != hwnd)
{
if( !bFullScreen )
{
Message("Lost palette but continuing");
}
}
break;
// case WM_SETCURSOR:
// if (bMouseVisible)
// SetCursor(LoadCursor(NULL, IDC_ARROW));
// else
// SetCursor(NULL);
// return TRUE;
// break;
case WM_CHAR:
if (lParam & (1 << 30))
return(0);
WriteKey((char) (wParam & 0xff));
return(0);
case WM_KEYDOWN:
Zdebug("key %d", wParam);
switch( wParam )
{
case VK_CONTROL:
controlKey = TRUE;
break;
// case VK_ALT:
// altKey = TRUE;
// break;
case 'W':
if (controlKey)
GrabScreenShot();
return 0;
case 'Q':
if (controlKey && !controlQDisabled)
DestroyWindow( hWnd );
return 0;
case 'F4':
DestroyWindow( hWnd );
return 0;
}
break;
case WM_KEYUP:
switch(wParam)
{
case VK_CONTROL:
controlKey = FALSE;
break;
// case VK_ALT:
// altKey = FALSE;
// break;
}
break;
case WM_DESTROY:
Zdebug("*destroy*");
if (wasScreenSaverActive)
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE , TRUE , 0 , 0 );
PostQuitMessage( 0 );
break;
case WM_MOUSEMOVE:
mousex = lParam & 0xffff;
if (bFullScreen)
{
mousey = (uint16) (lParam >> 16) - MENUDEEP;
}
else
{
mousey = (uint16) (lParam >> 16) - MENUDEEP;
if (mousex < 0)
mousex = 0;
if (mousex >= RENDERWIDE)
mousex = RENDERWIDE-1;
}
if (mousey < -MENUDEEP)
mousey = -MENUDEEP;
if (mousey >= RENDERDEEP + MENUDEEP)
mousey = RENDERDEEP + MENUDEEP - 1;
return(0);
case WM_LBUTTONDOWN:
LogMouseEvent(RD_LEFTBUTTONDOWN);
return(0);
case WM_LBUTTONUP:
LogMouseEvent(RD_LEFTBUTTONUP);
return(0);
case WM_RBUTTONDOWN:
LogMouseEvent(RD_RIGHTBUTTONDOWN);
return(0);
case WM_RBUTTONUP:
LogMouseEvent(RD_RIGHTBUTTONUP);
return(0);
case WM_LBUTTONDBLCLK:
LogMouseEvent(RD_LEFTBUTTONDOWN);
return(0);
case WM_RBUTTONDBLCLK:
LogMouseEvent(RD_RIGHTBUTTONDOWN);
case WM_SYSCOMMAND:
if (gotTheFocus)
return(0);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
*/
/*
int32 InitialiseWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, char *gameName)
{
WNDCLASS wc;
// uint32 err;
// hPrevInstance = hPrevInstance;
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = WindowsMessageHandler;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, "resourc1"); //IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = gameName;
wc.lpszClassName = gameName;
RegisterClass( &wc );
// Create a window
hwnd = CreateWindowEx(WS_EX_APPWINDOW, gameName, gameName, WS_VISIBLE | WS_SYSMENU | WS_POPUP, 0, 0,
GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ),
NULL, NULL, hInstance, NULL );
if(!hwnd)
{
MessageBox(hwnd, "Failed to create window", gameName, MB_OK );
DestroyWindow(hwnd);
return(RDERR_CREATEWINDOW);
}
// ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
SetFocus(hwnd);
SetTimer(hwnd, 25, 1000 / 25, NULL);
SetTimer(hwnd, 1, 100, NULL);
return(RD_OK);
}
*/
int32 CloseAppWindow(void)
{
warning("stub CloseAppWindow");
/*
DestroyWindow(hwnd);
*/
// just quit for now
g_system->quit();
return(RD_OK);
}
int32 ServiceWindows(void)
{
g_sword2->parseEvents();
FadeServer();
g_sword2->_system->update_screen();
// warning("stub ServiceWindows"); // too noisy
/*
MSG msg;
if (myAppClosed)
return(RDERR_APPCLOSED);
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0))
{
myAppClosed = TRUE;
return(RDERR_APPCLOSED);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
*/
return(RD_OK);
}
int32 _ReportDriverError(int32 error, const uint8 *filename, uint32 line)
{
warning("stub _ReportDriverError 0x%.8x file: %s, line: %d ", error, (const char *) filename, line);
/*
char errorText[128];
char name[80];
GetGameName(name);
sprintf(errorText, "Fatal error in %s, line %u! Code 0x%.8x", filename, line, error);
MessageBox(hwnd, errorText, name, MB_SYSTEMMODAL | MB_ICONHAND | MB_ABORTRETRYIGNORE);
*/
return(RD_OK);
}
int32 _ReportFatalError(const uint8 *error, const uint8 *filename, uint32 line)
{
warning("stub _ReportFatalError");
char errorText[500];
char name[80];
GetGameName((uint8 *)name);
sprintf(errorText, "FATAL ERROR - GAME TERMINATED\n%s", error);
//MessageBox(hwnd, errorText, name, MB_SYSTEMMODAL | MB_ICONHAND | MB_ABORTRETRYIGNORE);
warning("%s", errorText);
return(RD_OK);
}
int32 DisableQuitKey(void)
{
controlQDisabled = TRUE;
return(RD_OK);
}
void SetWindowName(const char *windowName)
{
warning("stub SetWindowName( %s )", windowName);
// SetWindowText(hwnd,windowName);
// strcpy(gameName,windowName);
}