scummvm/sword2/driver/rdwin.cpp

638 lines
13 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 "common/stdafx.h"
#include "common/engine.h"
#include "common/timer.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_engine->_timer->releaseProcedure(sword2_sound_handler);
g_system->quit();
return(RD_OK);
}
static bool _needRedraw = false;
void SetNeedRedraw() {
_needRedraw = true;
}
int32 ServiceWindows(void)
{
g_sword2->parseEvents();
FadeServer();
// FIXME: We re-render the entire picture area of the screen for each
// frame, which is pretty horrible.
if (_needRedraw) {
g_system->copy_rect(lpBackBuffer + MENUDEEP * screenWide, screenWide, 0, MENUDEEP, screenWide, screenDeep - 2 * MENUDEEP);
_needRedraw = false;
}
// We still need to update because of fades, menu animations, etc.
g_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);
}