- Removed the "USE_HIGHSPEED_GAMELOOP_TIMER" define. Now highspeed timer and new way of dequeuing events are always enabled when building an executable

o This makes the code more easy to maintain
o Highspeed timer seems to run fine (after months of tests)


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5643 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2012-10-25 19:00:12 +00:00
parent 888c76e65c
commit b1596f0c63
56 changed files with 669 additions and 1213 deletions
+33 -68
View File
@@ -111,9 +111,8 @@ BOOLEAN gfCurrentStringInputState;
StringInput *gpCurrentStringDescriptor;
// Thread
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
static CRITICAL_SECTION gcsInputQueueLock;
#endif
static CRITICAL_SECTION gcsInputQueueLock;
// Local function headers
@@ -282,9 +281,7 @@ BOOLEAN InitializeInputManager(void)
// ghKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) KeyboardHandler, (HINSTANCE) 0, GetCurrentThreadId());
// DbgMessage(TOPIC_INPUT, DBG_LEVEL_2, String("Set keyboard hook returned %d", ghKeyboardHook));
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
InitializeCriticalSection(&gcsInputQueueLock);
#endif
ghMouseHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC) MouseHandler, (HINSTANCE) 0, GetCurrentThreadId());
DbgMessage(TOPIC_INPUT, DBG_LEVEL_2, String("Set mouse hook returned %d", ghMouseHook));
@@ -299,10 +296,7 @@ void ShutdownInputManager(void)
// UnhookWindowsHookEx(ghKeyboardHook);
UnhookWindowsHookEx(ghMouseHook);
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
DeleteCriticalSection(&gcsInputQueueLock);
#endif
}
void QueuePureEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
@@ -343,11 +337,7 @@ void QueuePureEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
}
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
void InternalQueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
#else
void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
#endif
void InternalQueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
{
UINT32 uiTimer;
UINT16 usKeyState;
@@ -470,45 +460,21 @@ void QueuePureEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
}
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
{
EnterCriticalSection(&gcsInputQueueLock);
__try {
InternalQueueEvent(ubInputEvent, usParam, uiParam);
}__finally {
LeaveCriticalSection(&gcsInputQueueLock);
}
void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
{
EnterCriticalSection(&gcsInputQueueLock);
__try {
InternalQueueEvent(ubInputEvent, usParam, uiParam);
}__finally {
LeaveCriticalSection(&gcsInputQueueLock);
}
#endif
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
BOOLEAN DequeueSpecificEvent(InputAtom *Event, UINT32 uiMaskFlags )
{
EnterCriticalSection(&gcsInputQueueLock);
__try
{
// Is there an event to dequeue
if (gusQueueCount > 0)
{
memcpy( Event, &( gEventQueue[gusHeadIndex] ), sizeof( InputAtom ) );
// Check if it has the masks!
if ( ( Event->usEvent & uiMaskFlags ) )
{
return( DequeueEvent( Event) );
}
}
return( FALSE );
}
__finally
{
LeaveCriticalSection(&gcsInputQueueLock);
}
}
#else
BOOLEAN DequeueSpecificEvent(InputAtom *Event, UINT32 uiMaskFlags )
BOOLEAN DequeueSpecificEvent(InputAtom *Event, UINT32 uiMaskFlags )
{
EnterCriticalSection(&gcsInputQueueLock);
__try
{
// Is there an event to dequeue
if (gusQueueCount > 0)
@@ -524,13 +490,13 @@ void QueuePureEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
return( FALSE );
}
#endif
__finally
{
LeaveCriticalSection(&gcsInputQueueLock);
}
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
BOOLEAN InternalDequeueEvent(InputAtom *Event)
#else
BOOLEAN DequeueEvent(InputAtom *Event)
#endif
BOOLEAN InternalDequeueEvent(InputAtom *Event)
{
HandleSingleClicksAndButtonRepeats( );
@@ -562,20 +528,19 @@ void QueuePureEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
}
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
BOOLEAN DequeueEvent(InputAtom *Event)
BOOLEAN DequeueEvent(InputAtom *Event)
{
__try
{
__try
{
EnterCriticalSection(&gcsInputQueueLock);
return InternalDequeueEvent(Event);
}
__finally
{
LeaveCriticalSection(&gcsInputQueueLock);
}
EnterCriticalSection(&gcsInputQueueLock);
return InternalDequeueEvent(Event);
}
#endif
__finally
{
LeaveCriticalSection(&gcsInputQueueLock);
}
}
void KeyChange(UINT32 usParam, UINT32 uiParam, UINT8 ufKeyState)
{
+105 -136
View File
@@ -151,13 +151,13 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandSho
void ShutdownStandardGamingPlatform(void);
void GetRuntimeSettings( );
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
INT32 FAR PASCAL SyncWindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam);
void CreateStandardGamingPlatform(HWND hWindow);
void SafeSGPExit(void);
static bool CallGameLoop(bool wait);
static CRITICAL_SECTION gcsGameLoop;
#endif
INT32 FAR PASCAL SyncWindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam);
void CreateStandardGamingPlatform(HWND hWindow);
void SafeSGPExit(void);
static bool CallGameLoop(bool wait);
static CRITICAL_SECTION gcsGameLoop;
int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCommandLine, int sCommandShow);
@@ -216,16 +216,16 @@ BOOLEAN gfIgnoreMessages=FALSE;
// GLOBAL VARIBLE, SET TO DEFAULT BUT CAN BE CHANGED BY THE GAME IF INIT FILE READ
UINT8 gbPixelDepth = PIXEL_DEPTH;
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
INT32 FAR PASCAL SyncWindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam)
{
INT32 retval;
EnterCriticalSection(&gcsGameLoop);
retval = WindowProcedure(hWindow, Message, wParam, lParam);
LeaveCriticalSection(&gcsGameLoop);
return retval;
}
#endif
INT32 FAR PASCAL SyncWindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam)
{
INT32 retval;
EnterCriticalSection(&gcsGameLoop);
retval = WindowProcedure(hWindow, Message, wParam, lParam);
LeaveCriticalSection(&gcsGameLoop);
return retval;
}
bool s_bExportStrings = false;
extern bool g_bUseXML_Strings;// = false;
@@ -536,9 +536,7 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP
case WM_CREATE:
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
CreateStandardGamingPlatform(hWindow);
#endif
break;
case WM_DESTROY:
@@ -667,11 +665,7 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
FontTranslationTable *pFontTable;
// now required by all (even JA2) in order to call ShutdownSGP
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
atexit(SafeSGPExit);
#else
atexit(SGPExit);
#endif
// First, initialize the registry keys.
InitializeRegistryKeys( "Wizardry8", "Wizardry8key" );
@@ -732,9 +726,8 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
return FALSE;
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
InitializeCriticalSection(&gcsGameLoop);
#endif
FastDebugMsg("Initializing Video Manager");
// Initialize DirectDraw (DirectX 2)
@@ -761,13 +754,6 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
return FALSE;
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
#else
InitializeJA2Clock();
#endif
//InitializeJA2TimerID();
#ifdef USE_VFS
//vfs::Path exe_dir, exe_file;
//os::getExecutablePath(exe_dir, exe_file);
@@ -915,26 +901,25 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
return TRUE;
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
static void TimerActivatedCallback(INT32 timer, PTR state)
static void TimerActivatedCallback(INT32 timer, PTR state)
{
if (gfApplicationActive && gfProgramIsRunning)
{
if (gfApplicationActive && gfProgramIsRunning)
{
if (CallGameLoop(false))
YieldProcessor();
}
if (CallGameLoop(false))
YieldProcessor();
}
}
void CreateStandardGamingPlatform(HWND hWindow)
{
InitializeJA2Clock();
void CreateStandardGamingPlatform(HWND hWindow)
{
InitializeJA2Clock();
if (!IsHiSpeedClockMode())
SetTimer( hWindow, 0, 1, NULL);
else
AddTimerNotifyCallback(TimerActivatedCallback, hWindow);
}
if (!IsHiSpeedClockMode())
SetTimer( hWindow, 0, 1, NULL);
else
AddTimerNotifyCallback(TimerActivatedCallback, hWindow);
}
#endif
void ShutdownStandardGamingPlatform(void)
{
@@ -959,9 +944,7 @@ void ShutdownStandardGamingPlatform(void)
// Shut down the different components of the SGP
//
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
ClearTimerNotifyCallbacks();
#endif
// TEST
SoundServiceStreams();
@@ -1009,9 +992,7 @@ void ShutdownStandardGamingPlatform(void)
// down the debugging layer
UnRegisterDebugTopic(TOPIC_SGP, "Standard Gaming Platform");
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
DeleteCriticalSection(&gcsGameLoop);
#endif
ShutdownDebugManager();
@@ -1277,12 +1258,6 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
FastDebugMsg("Running Game");
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
#else
// 0verhaul: Use the smallest available timer to make sure all animation updates happen at the speed they're supposed to
SetTimer( ghWindow, uiTimer, 1, NULL);
#endif
// At this point the SGP is set up, which means all I/O, Memory, tools, etc... are available. All we need to do is
// attend to the gaming mechanics themselves
Message.wParam = 0;
@@ -1356,10 +1331,6 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
}
#endif
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
#else
KillTimer( ghWindow, uiTimer);
#endif
// This is the normal exit point
FastDebugMsg("Exiting Game");
@@ -1728,29 +1699,28 @@ void GetRuntimeSettings( )
s_CodePage = oProps.getStringProperty(L"Ja2 Settings", L"CODE_PAGE");
#endif // USE_CODE_PAGE
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
// get timer/clock initialization state
SetHiSpeedClockMode( oProps.getBoolProperty("Ja2 Settings", "HIGHSPEED_TIMER", false) ? TRUE : FALSE );
#endif
// get timer/clock initialization state
SetHiSpeedClockMode( oProps.getBoolProperty("Ja2 Settings", "HIGHSPEED_TIMER", false) ? TRUE : FALSE );
#endif
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
void SafeSGPExit(void)
void SafeSGPExit(void)
{
// SGPExit tends to use resources that are already uninitialized so handle
__try
{
// SGPExit tends to use resources that are already uninitialized so handle
__try
{
SGPExit();
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
// The application is in exit and best effort to clean up
// has failed so just ignore and continue silently
}
SGPExit();
}
#endif
__except( EXCEPTION_EXECUTE_HANDLER )
{
// The application is in exit and best effort to clean up
// has failed so just ignore and continue silently
}
}
void ShutdownWithErrorBox(CHAR8 *pcMessage)
{
@@ -1945,70 +1915,69 @@ static LONG __stdcall SGPExceptionFilter(int exceptionCount, EXCEPTION_POINTERS*
return EXCEPTION_EXECUTE_HANDLER;
}
#ifdef USE_HIGHSPEED_GAMELOOP_TIMER
static void SGPGameLoop()
static void SGPGameLoop()
{
try
{
try
{
GameLoop();
}
catch(sgp::Exception &ex)
{
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(vfs::Exception &ex)
{
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(std::exception &ex)
{
sgp::Exception nex(ex.what());
SGP_ERROR(nex.what());
SHOWEXCEPTION(nex);
}
catch(const char* msg)
{
sgp::Exception ex(msg);
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
GameLoop();
}
catch(sgp::Exception &ex)
{
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(vfs::Exception &ex)
{
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(std::exception &ex)
{
sgp::Exception nex(ex.what());
SGP_ERROR(nex.what());
SHOWEXCEPTION(nex);
}
catch(const char* msg)
{
sgp::Exception ex(msg);
SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
}
static bool CallGameLoop(bool wait)
{
static int numUnsuccessfulTries = 0;
if (wait)
{
EnterCriticalSection(&gcsGameLoop);
}
else
{
if ( !TryEnterCriticalSection(&gcsGameLoop) )
return false;
}
static bool CallGameLoop(bool wait)
__try
{
static int numUnsuccessfulTries = 0;
if (wait)
{
EnterCriticalSection(&gcsGameLoop);
}
else
{
if ( !TryEnterCriticalSection(&gcsGameLoop) )
return false;
}
__try
{
__try
{
SGPGameLoop();
numUnsuccessfulTries = 0;
}
__except( SGPExceptionFilter(++numUnsuccessfulTries, GetExceptionInformation()) )
{
}
SGPGameLoop();
numUnsuccessfulTries = 0;
}
__finally
__except( SGPExceptionFilter(++numUnsuccessfulTries, GetExceptionInformation()) )
{
LeaveCriticalSection(&gcsGameLoop);
}
// Give it several attempts to recover from random exceptions and to display error screen
if (numUnsuccessfulTries > 5)
ShutdownWithErrorBox("Unhandled exception. Unable to recover.");
return true;
}
#endif
__finally
{
LeaveCriticalSection(&gcsGameLoop);
}
// Give it several attempts to recover from random exceptions and to display error screen
if (numUnsuccessfulTries > 5)
ShutdownWithErrorBox("Unhandled exception. Unable to recover.");
return true;
}