From e8027d6663ca37e52a8376ba5515eac2befedd68 Mon Sep 17 00:00:00 2001 From: Wanne Date: Mon, 25 Jun 2012 15:06:04 +0000 Subject: [PATCH] - Made the "Highspeed timer game loop (FF-MOD by tazpn)" optional, so we can decide if we like to build an executable with/without the highspeed timer o See: builddefines.h: #define USE_HIGHSPEED_GAMELOOP_TIMER o Gamers reported on the Bears Pit, that an executable compiled WITH the highspeed timer enabled makes the game unplayable slow in mapscreen mode when doing certain actions (repair, ...). That is the reason, why I made the compilation of the highspeed timer optional. Currently it is disabled. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5355 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Credits.cpp | 4 + Editor/messagebox.cpp | 5 + Editor/popupmenu.cpp | 6 + GameInitOptionsScreen.cpp | 8 + GameSettings.cpp | 19 +- GameSettings.h | 6 + GameVersion.cpp | 18 +- Laptop/AimMembers.cpp | 5 + Laptop/BobbyRGuns.cpp | 2 + Laptop/BriefingRoom.cpp | 4 + Laptop/BriefingRoomM.cpp | 4 + Laptop/IMP Begin Screen.cpp | 4 + Laptop/IMP HomePage.cpp | 4 + Laptop/florist Order Form.cpp | 4 + Laptop/mercs Files.cpp | Bin 69640 -> 69832 bytes Laptop/personnel.cpp | 4 + MPChatScreen.cpp | 5 + MPConnectScreen.cpp | 4 + MPHostScreen.cpp | 4 + MPJoinScreen.cpp | 4 + MPScoreScreen.cpp | 4 + MainMenuScreen.cpp | 8 + MessageBoxScreen.cpp | 4 + Options Screen.cpp | Bin 129020 -> 129492 bytes SaveLoadGame.cpp | 2 + Standard Gaming Platform/input.cpp | 100 ++- Standard Gaming Platform/sgp.cpp | 234 +++--- Strategic/AI Viewer.cpp | 5 + Strategic/Auto Resolve.cpp | 5 + Strategic/Quest Debug System.cpp | 4 + Strategic/mapscreen.cpp | 33 +- Tactical/Auto Bandage.cpp | 4 + Tactical/ShopKeeper Interface.cpp | 4 + Tactical/Strategic Exit GUI.cpp | 4 + Tactical/Tactical Turns.cpp | 2 + Tactical/TeamTurns.cpp | 9 + TileEngine/overhead map.cpp | 4 + Utils/MapUtility.cpp | 4 + Utils/Timer Control.cpp | 1176 ++++++++++++++++------------ Utils/Timer Control.h | 114 ++- Utils/Utils All.h | 6 +- Utils/_ChineseText.cpp | 8 + Utils/_DutchText.cpp | 8 + Utils/_EnglishText.cpp | 8 + Utils/_FrenchText.cpp | 8 + Utils/_GermanText.cpp | 8 + Utils/_ItalianText.cpp | 8 + Utils/_PolishText.cpp | 8 + Utils/_RussianText.cpp | 8 + Utils/_TaiwaneseText.cpp | 8 + aniviewscreen.cpp | 4 + builddefines.h | 5 + gameloop.cpp | 33 +- gameloop.h | 6 +- jascreens.cpp | 4 + 55 files changed, 1277 insertions(+), 687 deletions(-) diff --git a/Credits.cpp b/Credits.cpp index 3dab0450..a2416143 100644 --- a/Credits.cpp +++ b/Credits.cpp @@ -417,7 +417,11 @@ void GetCreditScreenUserInput() { InputAtom Event; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { if( Event.usEvent == KEY_DOWN ) { diff --git a/Editor/messagebox.cpp b/Editor/messagebox.cpp index 2a2b5eaf..89207a0c 100644 --- a/Editor/messagebox.cpp +++ b/Editor/messagebox.cpp @@ -76,7 +76,12 @@ BOOLEAN MessageBoxHandled() { InputAtom DummyEvent; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&DummyEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &DummyEvent ) ) +#endif + { if ( DummyEvent.usEvent == KEY_DOWN ) { diff --git a/Editor/popupmenu.cpp b/Editor/popupmenu.cpp index d80cab2f..e20ffde3 100644 --- a/Editor/popupmenu.cpp +++ b/Editor/popupmenu.cpp @@ -397,7 +397,13 @@ void PopupMenuHandle() return; } //Use keyboard input as well. + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &InputEvent ) ) +#endif + { switch(InputEvent.usEvent) { diff --git a/GameInitOptionsScreen.cpp b/GameInitOptionsScreen.cpp index a462778d..b6b6626b 100644 --- a/GameInitOptionsScreen.cpp +++ b/GameInitOptionsScreen.cpp @@ -2578,7 +2578,11 @@ void GetGIOScreenUserInput() { InputAtom Event; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { if( Event.usEvent == KEY_DOWN ) { @@ -5398,7 +5402,11 @@ void GetGIOScreenUserInput() { InputAtom Event; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { if( Event.usEvent == KEY_DOWN ) { diff --git a/GameSettings.cpp b/GameSettings.cpp index cce439d1..19e40576 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -38,8 +38,11 @@ #include "InterfaceItemImages.h" #endif -#include "KeyMap.h" -#include "Timer Control.h" +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + #include "KeyMap.h" + #include "Timer Control.h" +#endif + #include "Text.h" #include "connect.h" #include "sgp_logger.h" @@ -240,6 +243,7 @@ BOOLEAN LoadGameSettings() gGameSettings.fOptions[TOPTION_QUIET_REPAIRING] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_QUIET_REPAIRING" , FALSE ); gGameSettings.fOptions[TOPTION_QUIET_DOCTORING] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_QUIET_DOCTORING" , FALSE ); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER if (!is_networked) gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_AUTO_FAST_FORWARD_MODE" , FALSE ); else @@ -248,6 +252,7 @@ BOOLEAN LoadGameSettings() // The "HIGHSPEED_TIMER" property from the ja2.ini is not set, disable the option if (!IsHiSpeedClockMode()) gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] = FALSE; +#endif gGameSettings.fOptions[TOPTION_ZOMBIES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ZOMBIES" , FALSE ); @@ -407,7 +412,11 @@ BOOLEAN SaveGameSettings() settings << "TOPTION_QUIET_TRAINING = " << (gGameSettings.fOptions[TOPTION_QUIET_TRAINING] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_QUIET_REPAIRING = " << (gGameSettings.fOptions[TOPTION_QUIET_REPAIRING] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_QUIET_DOCTORING = " << (gGameSettings.fOptions[TOPTION_QUIET_DOCTORING] ? "TRUE" : "FALSE" ) << endl; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER settings << "TOPTION_AUTO_FAST_FORWARD_MODE = " << (gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] ? "TRUE" : "FALSE" ) << endl; +#endif + settings << "TOPTION_ZOMBIES = " << (gGameSettings.fOptions[TOPTION_ZOMBIES] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_CHEAT_MODE_OPTIONS_HEADER = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_HEADER] ? "TRUE" : "FALSE" ) << endl; settings << "TOPTION_FORCE_BOBBY_RAY_SHIPMENTS = " << (gGameSettings.fOptions[TOPTION_FORCE_BOBBY_RAY_SHIPMENTS] ? "TRUE" : "FALSE" ) << endl; @@ -535,7 +544,11 @@ void InitGameSettings() gGameSettings.fOptions[ TOPTION_QUIET_TRAINING ] = FALSE; gGameSettings.fOptions[ TOPTION_QUIET_REPAIRING ] = FALSE; gGameSettings.fOptions[ TOPTION_QUIET_DOCTORING ] = FALSE; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER gGameSettings.fOptions[ TOPTION_AUTO_FAST_FORWARD_MODE ] = FALSE; +#endif + gGameSettings.fOptions[ TOPTION_ZOMBIES ] = FALSE; // Flugente Zombies 1.0 @@ -1794,6 +1807,7 @@ void LoadGameExternalOptions() gGameExternalOptions.fEnableInventoryPoolQ = FALSE; #endif +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER ////////// CLOCK SETTINGS ////////// // Key to artificially alter the clock so turns run faster @@ -1804,6 +1818,7 @@ void LoadGameExternalOptions() gGameExternalOptions.iFastForwardPeriod = (FLOAT)iniReader.ReadDouble("Clock Settings","FAST_FORWARD_PERIOD", 500, 1, 10000); gGameExternalOptions.fClockSpeedPercent = (FLOAT)iniReader.ReadDouble("Clock Settings","CLOCK_SPEED_PERCENT", 150, 100, 300); gGameExternalOptions.iNotifyFrequency = iniReader.ReadInteger("Clock Settings","UPDATE_FREQUENCY", 16000, 1000, 20000); +#endif } diff --git a/GameSettings.h b/GameSettings.h index 9b3354a9..2dbc12b3 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -90,7 +90,11 @@ enum TOPTION_QUIET_TRAINING, //Madd: mercs don't say gained experience quote while training TOPTION_QUIET_REPAIRING, //Madd: mercs don't say gained experience quote while repairing items TOPTION_QUIET_DOCTORING, //Madd: mercs don't say gained experience quote while doctoring + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER TOPTION_AUTO_FAST_FORWARD_MODE, // automatically fast forward through AI turns +#endif + TOPTION_ZOMBIES, // Flugente Zombies 1.0: allow zombies // arynn: Debug/Cheat @@ -1083,6 +1087,7 @@ typedef struct INT32 iInitialMercArrivalLocation; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER // Keyboard shortcut (as VK) for fastforward key. See Utils/KeyMap INT32 iFastForwardKey; // Turn on fast forward whenever ui is disabled. @@ -1093,6 +1098,7 @@ typedef struct INT32 iNotifyFrequency; // Frequency that the screen is updated FLOAT fClockSpeedPercent; +#endif // Flugente FTW 1: Weapon Overheating BOOLEAN fDisplayOverheatThermometer; // Should a 'thermometer' for guns and replacable barrels be displayed? diff --git a/GameVersion.cpp b/GameVersion.cpp index 680966d5..4016d1ed 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.5354 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.5354 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.5354 (Development Build)" }; #elif defined (JA113DEMO) || defined (JA113NODEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.5354 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.5354 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.5354 (Development Build)" }; #elif defined (JA113DEMO) || defined (JA113NODEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.5354 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.5353 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.5354 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 19.06.12" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 25.06.12" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/Laptop/AimMembers.cpp b/Laptop/AimMembers.cpp index 8721e322..82e1e7bf 100644 --- a/Laptop/AimMembers.cpp +++ b/Laptop/AimMembers.cpp @@ -5020,7 +5020,12 @@ void HandleAimMemberKeyBoardInput() { InputAtom InputEvent; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif + {//!HandleTextInput( &InputEvent ) && if( InputEvent.usEvent == KEY_DOWN ) { diff --git a/Laptop/BobbyRGuns.cpp b/Laptop/BobbyRGuns.cpp index 1ec33fdc..440e5a63 100644 --- a/Laptop/BobbyRGuns.cpp +++ b/Laptop/BobbyRGuns.cpp @@ -4053,10 +4053,12 @@ void HandleBobbyRGunsKeyBoardInput() break; } } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER else { extern void HandleDefaultEvent(InputAtom *Event); HandleDefaultEvent(&InputEvent); } +#endif } } diff --git a/Laptop/BriefingRoom.cpp b/Laptop/BriefingRoom.cpp index 49dc1149..f0df185d 100644 --- a/Laptop/BriefingRoom.cpp +++ b/Laptop/BriefingRoom.cpp @@ -426,7 +426,11 @@ void GetPlayerKeyBoardInputForBriefingRoomHomePage( void ) GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { // HOOK INTO MOUSE HOOKS /* diff --git a/Laptop/BriefingRoomM.cpp b/Laptop/BriefingRoomM.cpp index 4bcaef4a..2ac211d8 100644 --- a/Laptop/BriefingRoomM.cpp +++ b/Laptop/BriefingRoomM.cpp @@ -493,7 +493,11 @@ void GetPlayerKeyBoardInputForBriefingRoomEnterHomePage( void ) GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { // HOOK INTO MOUSE HOOKS /* diff --git a/Laptop/IMP Begin Screen.cpp b/Laptop/IMP Begin Screen.cpp index 3df5b16e..c6151d0b 100644 --- a/Laptop/IMP Begin Screen.cpp +++ b/Laptop/IMP Begin Screen.cpp @@ -455,7 +455,11 @@ void GetPlayerKeyBoardInputForIMPBeginScreen( void ) ScreenToClient(ghWindow, &MousePos); // In window coords! // handle input events +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent(&InputEvent) ) +#endif { if( !HandleTextInput( &InputEvent ) && (InputEvent.usEvent == KEY_DOWN || InputEvent.usEvent == KEY_REPEAT) ) { diff --git a/Laptop/IMP HomePage.cpp b/Laptop/IMP HomePage.cpp index 0db4b321..8dd8a1df 100644 --- a/Laptop/IMP HomePage.cpp +++ b/Laptop/IMP HomePage.cpp @@ -266,7 +266,11 @@ void GetPlayerKeyBoardInputForIMPHomePage( void ) GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if( !HandleTextInput( &InputEvent ) && (InputEvent.usEvent == KEY_DOWN || InputEvent.usEvent == KEY_REPEAT || InputEvent.usEvent == KEY_UP ) ) { diff --git a/Laptop/florist Order Form.cpp b/Laptop/florist Order Form.cpp index b77a6478..882945fc 100644 --- a/Laptop/florist Order Form.cpp +++ b/Laptop/florist Order Form.cpp @@ -1257,7 +1257,11 @@ void HandleFloristOrderKeyBoardInput() { InputAtom InputEvent; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if( !HandleTextInput( &InputEvent ) && InputEvent.usEvent == KEY_DOWN ) { diff --git a/Laptop/mercs Files.cpp b/Laptop/mercs Files.cpp index 83bc74accd3c2d01bf4a443318617321ef405369..9839f9a5f63c0e54d2398725100fa87f6893dced 100644 GIT binary patch delta 142 zcmeBJz;a?C%Z6{?U6mO!8PXV17*c_x0z)W6FoP>YJc9>=CxbhX3}y%b@?9BRfMV_p zjtss)whx0p5C#B6LV&73B0-ZsexJ&z3^XH$p_m~R$WxxI@5Gnvw1_8}> YWzb~cW#D1}smue~3AA~0= '0' ) && ( InputEvent.usParam <= '9') ) { diff --git a/MPChatScreen.cpp b/MPChatScreen.cpp index 1eac5143..3f247fcb 100644 --- a/MPChatScreen.cpp +++ b/MPChatScreen.cpp @@ -757,7 +757,12 @@ UINT32 MPChatScreenHandle( ) // carter, need key shortcuts for clearing up message boxes // Check for esc bool bHandled; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { bHandled = false; if(InputEvent.usEvent == KEY_DOWN ) diff --git a/MPConnectScreen.cpp b/MPConnectScreen.cpp index 1b2ca83a..cafad384 100644 --- a/MPConnectScreen.cpp +++ b/MPConnectScreen.cpp @@ -418,7 +418,11 @@ void GetMPCScreenUserInput() // GetCursorPos(&MousePos); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { // check if this event is swallowed by text input, otherwise process key if( Event.usEvent == KEY_DOWN ) diff --git a/MPHostScreen.cpp b/MPHostScreen.cpp index 17de7c7c..a1883c97 100644 --- a/MPHostScreen.cpp +++ b/MPHostScreen.cpp @@ -2740,7 +2740,11 @@ void GetMPHScreenUserInput() // GetCursorPos(&MousePos); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { // check if this event is swallowed by text input, otherwise process key if( !HandleTextInput( &Event ) && Event.usEvent == KEY_DOWN ) diff --git a/MPJoinScreen.cpp b/MPJoinScreen.cpp index 9b2b6112..42ebad0d 100644 --- a/MPJoinScreen.cpp +++ b/MPJoinScreen.cpp @@ -665,7 +665,11 @@ void GetMPJScreenUserInput() { InputAtom Event; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { // check if this event is swallowed by text input, otherwise process key if( !HandleTextInput( &Event ) && Event.usEvent == KEY_DOWN ) diff --git a/MPScoreScreen.cpp b/MPScoreScreen.cpp index b3c64214..e3ab8e7d 100644 --- a/MPScoreScreen.cpp +++ b/MPScoreScreen.cpp @@ -536,7 +536,11 @@ void GetMPSScreenUserInput() { InputAtom Event; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { // check if this event is swallowed by text input, otherwise process key if( !HandleTextInput( &Event ) && Event.usEvent == KEY_DOWN ) diff --git a/MainMenuScreen.cpp b/MainMenuScreen.cpp index 32ce4178..acc07de5 100644 --- a/MainMenuScreen.cpp +++ b/MainMenuScreen.cpp @@ -484,7 +484,11 @@ void HandleMainMenuInput() InputAtom InputEvent; // Check for esc +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if( InputEvent.usEvent == KEY_UP ) { @@ -533,7 +537,11 @@ void HandleHelpScreenInput() InputAtom InputEvent; // Check for key +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { switch( InputEvent.usEvent ) { diff --git a/MessageBoxScreen.cpp b/MessageBoxScreen.cpp index 55ba137a..dda3ca1d 100644 --- a/MessageBoxScreen.cpp +++ b/MessageBoxScreen.cpp @@ -1306,7 +1306,11 @@ UINT32 MessageBoxScreenHandle( ) // carter, need key shortcuts for clearing up message boxes // Check for esc +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if( !HandleTextInput( &InputEvent ) && InputEvent.usEvent == KEY_DOWN ) { diff --git a/Options Screen.cpp b/Options Screen.cpp index d50096f9622dccab10d9491e54f89363d96353dd..31d598319967129a31451fd95902c39d254acd70 100644 GIT binary patch delta 497 zcmezKp8d*a_J%EtWmCPC88R8t7*ZHgfusUMC_^xVD?>bk2ZJYrJCF=!2mtb38C-y3 z?hK9$zCgAQgFg@k07XK8sz4$^47?0n44l(*r!sm@mvUtknXa>#F=D#RG{&mw3h|6A z)Bi1I6q~-shEZVp4G%_*$$G2hT&ZI3^z(}tW2f)yVq}|cGo5kCbgjjVQPbxvWpn}A mJ&#)%=&L-S-+(@x?)ZXHe7oFC#(kV4$;-mq8 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 ) { // Is there an event to dequeue if (gusQueueCount > 0) @@ -487,13 +524,13 @@ BOOLEAN DequeueSpecificEvent(InputAtom *Event, UINT32 uiMaskFlags ) return( FALSE ); } - __finally - { - LeaveCriticalSection(&gcsInputQueueLock); - } -} +#endif -BOOLEAN InternalDequeueEvent(InputAtom *Event) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + BOOLEAN InternalDequeueEvent(InputAtom *Event) +#else + BOOLEAN DequeueEvent(InputAtom *Event) +#endif { HandleSingleClicksAndButtonRepeats( ); @@ -524,18 +561,21 @@ BOOLEAN InternalDequeueEvent(InputAtom *Event) return FALSE; } } -BOOLEAN DequeueEvent(InputAtom *Event) -{ - __try + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + BOOLEAN DequeueEvent(InputAtom *Event) { - EnterCriticalSection(&gcsInputQueueLock); - return InternalDequeueEvent(Event); + __try + { + EnterCriticalSection(&gcsInputQueueLock); + return InternalDequeueEvent(Event); + } + __finally + { + LeaveCriticalSection(&gcsInputQueueLock); + } } - __finally - { - LeaveCriticalSection(&gcsInputQueueLock); - } -} +#endif void KeyChange(UINT32 usParam, UINT32 uiParam, UINT8 ufKeyState) { diff --git a/Standard Gaming Platform/sgp.cpp b/Standard Gaming Platform/sgp.cpp index ee5eeff6..d2932869 100644 --- a/Standard Gaming Platform/sgp.cpp +++ b/Standard Gaming Platform/sgp.cpp @@ -56,8 +56,8 @@ #define USE_CONSOLE 0 #include - #include + #include "ExceptionHandling.h" #include "dbt.h" @@ -146,16 +146,18 @@ extern BOOLEAN CheckIfGameCdromIsInCDromDrive(); extern void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam); // Prototype Declarations -INT32 FAR PASCAL SyncWindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam); INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam); BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow); void ShutdownStandardGamingPlatform(void); -void CreateStandardGamingPlatform(HWND hWindow); void GetRuntimeSettings( ); -void SafeSGPExit(void); -static bool CallGameLoop(bool wait); -static CRITICAL_SECTION gcsGameLoop; +#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 int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCommandLine, int sCommandShow); @@ -214,14 +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; -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; -} +#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 bool s_bExportStrings = false; extern bool g_bUseXML_Strings;// = false; @@ -531,7 +535,10 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP break; case WM_CREATE: + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER CreateStandardGamingPlatform(hWindow); +#endif break; case WM_DESTROY: @@ -660,7 +667,11 @@ 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" ); @@ -721,7 +732,9 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow) return FALSE; } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER InitializeCriticalSection(&gcsGameLoop); +#endif FastDebugMsg("Initializing Video Manager"); // Initialize DirectDraw (DirectX 2) @@ -748,6 +761,11 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow) return FALSE; } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER +#else + InitializeJA2Clock(); +#endif + //InitializeJA2TimerID(); #ifdef USE_VFS @@ -897,24 +915,26 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow) return TRUE; } -static void TimerActivatedCallback(INT32 timer, PTR state) -{ - if (gfApplicationActive && gfProgramIsRunning) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + static void TimerActivatedCallback(INT32 timer, PTR state) { - if (CallGameLoop(false)) - YieldProcessor(); + if (gfApplicationActive && gfProgramIsRunning) + { + 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) { @@ -938,7 +958,10 @@ void ShutdownStandardGamingPlatform(void) // // Shut down the different components of the SGP // + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER ClearTimerNotifyCallbacks(); +#endif // TEST SoundServiceStreams(); @@ -986,7 +1009,9 @@ void ShutdownStandardGamingPlatform(void) // down the debugging layer UnRegisterDebugTopic(TOPIC_SGP, "Standard Gaming Platform"); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER DeleteCriticalSection(&gcsGameLoop); +#endif ShutdownDebugManager(); @@ -1252,6 +1277,12 @@ 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; @@ -1325,6 +1356,11 @@ 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"); PostQuitMessage(0); @@ -1685,26 +1721,29 @@ 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 + +#endif } - -void SafeSGPExit(void) -{ - // SGPExit tends to use resources that are already uninitialized so handle - __try +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + void SafeSGPExit(void) { - SGPExit(); + // 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 + } } - __except( EXCEPTION_EXECUTE_HANDLER ) - { - // The application is in exit and best effort to clean up - // has failed so just ignore and continue silently - } -} - +#endif void ShutdownWithErrorBox(CHAR8 *pcMessage) { @@ -1899,69 +1938,70 @@ static LONG __stdcall SGPExceptionFilter(int exceptionCount, EXCEPTION_POINTERS* return EXCEPTION_EXECUTE_HANDLER; } -static void SGPGameLoop() -{ - try +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + static void SGPGameLoop() { - 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; + 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); + } } - __try + static bool CallGameLoop(bool wait) { + static int numUnsuccessfulTries = 0; + if (wait) + { + EnterCriticalSection(&gcsGameLoop); + } + else + { + if ( !TryEnterCriticalSection(&gcsGameLoop) ) + return false; + } + __try { - SGPGameLoop(); - numUnsuccessfulTries = 0; + __try + { + SGPGameLoop(); + numUnsuccessfulTries = 0; + } + __except( SGPExceptionFilter(++numUnsuccessfulTries, GetExceptionInformation()) ) + { + } } - __except( SGPExceptionFilter(++numUnsuccessfulTries, GetExceptionInformation()) ) + __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; } - __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; -} - +#endif diff --git a/Strategic/AI Viewer.cpp b/Strategic/AI Viewer.cpp index 1a15c9d0..fdb6cc2a 100644 --- a/Strategic/AI Viewer.cpp +++ b/Strategic/AI Viewer.cpp @@ -932,7 +932,12 @@ void HandleViewerInput() { SECTORINFO *pSector; InputAtom Event; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while( DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP) ) +#else + while( DequeueEvent( &Event ) ) +#endif { if( !HandleTextInput( &Event ) && Event.usEvent == KEY_DOWN ) { diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index 016e9755..646c585c 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -3410,7 +3410,12 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve3"); InputAtom InputEvent; BOOLEAN fResetAutoResolve = FALSE; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while( DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT) ) +#else + while( DequeueEvent( &InputEvent ) ) +#endif { if( InputEvent.usEvent == KEY_DOWN || InputEvent.usEvent == KEY_REPEAT ) { diff --git a/Strategic/Quest Debug System.cpp b/Strategic/Quest Debug System.cpp index ec2ae91a..dff6bb76 100644 --- a/Strategic/Quest Debug System.cpp +++ b/Strategic/Quest Debug System.cpp @@ -1311,7 +1311,11 @@ void GetUserInput() GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while( DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT) ) +#else + while( DequeueEvent( &Event ) ) +#endif { if( !HandleTextInput( &Event ) && Event.usEvent == KEY_DOWN ) { diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index 54b5df09..ef75a6d2 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -6811,6 +6811,7 @@ void InitializeWorldSize(INT16 sSectorX, INT16 sSectorY , INT8 bSectorZ) void GetMapKeyboardInput( UINT32 *puiNewEvent ) { InputAtom InputEvent; + POINT MousePos; INT8 bSquadNumber; UINT8 ubGroupId = 0; BOOLEAN fCtrl, fAlt; @@ -6822,9 +6823,37 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent ) fCtrl = _KeyDown( CTRL ); fAlt = _KeyDown( ALT ); -// while( DequeueEvent( &InputEvent ) ) - while( DequeueSpecificEvent( &InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT ) ) // doesn't work for some reason -- MM: fixed? it works better for me like this + while( DequeueEvent( &InputEvent ) ) { + #ifdef USE_HIGHSPEED_GAMELOOP_TIMER + #else + GetCursorPos(&MousePos); + ScreenToClient(ghWindow, &MousePos); // In window coords! + + // HOOK INTO MOUSE HOOKS + switch(InputEvent.usEvent) + { + case LEFT_BUTTON_DOWN: + MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case LEFT_BUTTON_UP: + MouseSystemHook(LEFT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y ,_LeftButtonDown, _RightButtonDown); + break; + case RIGHT_BUTTON_DOWN: + MouseSystemHook(RIGHT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case RIGHT_BUTTON_UP: + MouseSystemHook(RIGHT_BUTTON_UP, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case RIGHT_BUTTON_REPEAT: + MouseSystemHook(RIGHT_BUTTON_REPEAT, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + case LEFT_BUTTON_REPEAT: + MouseSystemHook(LEFT_BUTTON_REPEAT, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown); + break; + } + #endif + if( InputEvent.usEvent == KEY_DOWN ) { // if game is paused because of player, unpause with any key diff --git a/Tactical/Auto Bandage.cpp b/Tactical/Auto Bandage.cpp index 63528479..e749eddb 100644 --- a/Tactical/Auto Bandage.cpp +++ b/Tactical/Auto Bandage.cpp @@ -279,7 +279,11 @@ BOOLEAN HandleAutoBandage( ) // Deque all game events DequeAllGameEvents( TRUE ); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if ( InputEvent.usEvent == KEY_UP ) { diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index 4c7a7190..5b728c1f 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -1738,7 +1738,11 @@ void GetShopKeeperInterfaceUserInput() GetCursorPos(&MousePos); ScreenToClient(ghWindow, &MousePos); // In window coords! +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { // HOOK INTO MOUSE HOOKS /* removed warning condition C4060 (jonathanl) diff --git a/Tactical/Strategic Exit GUI.cpp b/Tactical/Strategic Exit GUI.cpp index f6ff728b..3506f84e 100644 --- a/Tactical/Strategic Exit GUI.cpp +++ b/Tactical/Strategic Exit GUI.cpp @@ -620,7 +620,11 @@ void RenderSectorExitMenu( ) gsGlobalCursorYOffset = 0; SetCurrentCursorFromDatabase( CURSOR_NORMAL ); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&Event, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while( DequeueEvent( &Event ) ) +#endif { if( Event.usEvent == KEY_DOWN ) { diff --git a/Tactical/Tactical Turns.cpp b/Tactical/Tactical Turns.cpp index 555ece2e..7a83432c 100644 --- a/Tactical/Tactical Turns.cpp +++ b/Tactical/Tactical Turns.cpp @@ -151,7 +151,9 @@ void HandleTacticalEndTurn( ) // OK, Do a number of things here.... // Every few turns...... +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER SetFastForwardMode(FALSE); // Cancel FF at end of battle +#endif // Get time elasped uiTime = GetWorldTotalSeconds( ); diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index c74cdd1d..55895647 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -167,7 +167,10 @@ void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode ) DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StartPlayerTeamTurn"); // SOLDIERTYPE *pSoldier; // EV_S_BEGINTURN SBeginTurn; + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER SetFastForwardMode(FALSE); +#endif // Start the turn of player charactors @@ -496,6 +499,7 @@ void BeginTeamTurn( UINT8 ubTeam ) if( !LightningEndOfTurn( ubTeam ) )return; //end rain +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER // disable for our turn and enable for other teams if ( gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] ) { @@ -510,6 +514,7 @@ void BeginTeamTurn( UINT8 ubTeam ) SetFastForwardMode( (ubTeam != OUR_TEAM) ); } } +#endif while( 1 ) { @@ -837,7 +842,9 @@ void StartInterrupt( void ) INT32 iSquad, iCounter; // disable ff mode +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER SetFastForwardMode(FALSE); +#endif // build string for display of who gets interrupt //while( 1 ) @@ -1432,6 +1439,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred ) } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER if ( gGameSettings.fOptions[TOPTION_AUTO_FAST_FORWARD_MODE] ) { if (is_networked) @@ -1445,6 +1453,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred ) SetFastForwardMode( (gTacticalStatus.ubCurrentTeam != OUR_TEAM) ); } } +#endif } diff --git a/TileEngine/overhead map.cpp b/TileEngine/overhead map.cpp index b4413f1e..8dd9e232 100644 --- a/TileEngine/overhead map.cpp +++ b/TileEngine/overhead map.cpp @@ -674,7 +674,11 @@ void HandleOverheadUI(void) ScrollOverheadMap(); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while(DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT) == TRUE) +#else + while(DequeueEvent(&InputEvent) == TRUE) +#endif { if(InputEvent.usEvent == KEY_DOWN || InputEvent.usEvent == KEY_REPEAT) { diff --git a/Utils/MapUtility.cpp b/Utils/MapUtility.cpp index 5a6ced33..08bbd955 100644 --- a/Utils/MapUtility.cpp +++ b/Utils/MapUtility.cpp @@ -101,7 +101,11 @@ UINT32 MapUtilScreenHandle(void) INT32 cnt, iX, iY, iSubX1, iSubY1, iSubX2, iSubY2, iWindowX, iWindowY, iCount; FLOAT dX, dY, dStartX, dStartY; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while(DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP) == TRUE) +#else + while(DequeueEvent(&InputEvent) == TRUE) +#endif { if(InputEvent.usParam == ESC) { diff --git a/Utils/Timer Control.cpp b/Utils/Timer Control.cpp index 4405b237..9389b102 100644 --- a/Utils/Timer Control.cpp +++ b/Utils/Timer Control.cpp @@ -14,9 +14,13 @@ #include "worlddef.h" #include "renderworld.h" #include "interface control.h" + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER #include "keymap.h" #endif +#endif + #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -25,11 +29,13 @@ #include "connect.h" // Base resolution of callback timer -static INT32 BASETIMESLICE = 10; -const INT32 FASTFORWARDTIMESLICE = 1000; -const UINT32 FREQUENCY_CONST = 1000000; -static INT32 MIN_NOTIFY_TIME = 16000; -static INT32 UPDATETIMESLICE = 10000; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + static INT32 BASETIMESLICE = 10; + const INT32 FASTFORWARDTIMESLICE = 1000; + const UINT32 FREQUENCY_CONST = 1000000; + static INT32 MIN_NOTIFY_TIME = 16000; + static INT32 UPDATETIMESLICE = 10000; +#endif INT32 giClockTimer = -1; INT32 giTimerDiag = 0; @@ -38,19 +44,22 @@ UINT32 guiBaseJA2Clock = 0; UINT32 guiBaseJA2NoPauseClock = 0; BOOLEAN gfPauseClock = FALSE; -BOOLEAN gfHispeedClockMode = FALSE; -const inline UINT32 TIME_US_TO_MS(UINT32 value) { return value / 1000; } -const inline UINT32 TIME_MS_TO_US(UINT32 value) { return value * 1000; } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + BOOLEAN gfHispeedClockMode = FALSE; -UINT32 giFastForwardPeriod = FASTFORWARDTIMESLICE; -BOOLEAN giFastForwardMode = FALSE; -INT32 giFastForwardKey = 0; -UINT32 guiTimeSlice = 0; -FLOAT gfClockSpeedPercent = 1.0; -LARGE_INTEGER gliPerfFreq = {0}; -LARGE_INTEGER gliPerfCount = {0}; -LARGE_INTEGER gliPerfCountNext = {0}; + const inline UINT32 TIME_US_TO_MS(UINT32 value) { return value / 1000; } + const inline UINT32 TIME_MS_TO_US(UINT32 value) { return value * 1000; } + + UINT32 giFastForwardPeriod = FASTFORWARDTIMESLICE; + BOOLEAN giFastForwardMode = FALSE; + INT32 giFastForwardKey = 0; + UINT32 guiTimeSlice = 0; + FLOAT gfClockSpeedPercent = 1.0; + LARGE_INTEGER gliPerfFreq = {0}; + LARGE_INTEGER gliPerfCount = {0}; + LARGE_INTEGER gliPerfCountNext = {0}; +#endif INT32 giTimerIntervals[ NUMTIMERS ] = { @@ -95,16 +104,19 @@ CUSTOMIZABLE_TIMER_CALLBACK gpCustomizableTimerCallback = NULL; // Clock Callback event ID MMRESULT gTimerID; -TIMECAPS gtc; -HANDLE ghClockThread; -DWORD gdwClockThreadId; -HANDLE ghClockThreadShutdown; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + TIMECAPS gtc; -HANDLE ghNotifyThread; -DWORD gdwNotifyThreadId; -HANDLE ghNotifyThreadEvent; -HANDLE ghNotifyThreadShutdownComplete; + HANDLE ghClockThread; + DWORD gdwClockThreadId; + HANDLE ghClockThreadShutdown; + + HANDLE ghNotifyThread; + DWORD gdwNotifyThreadId; + HANDLE ghNotifyThreadEvent; + HANDLE ghNotifyThreadShutdownComplete; +#endif // GLOBALS FOR CALLBACK UINT32 gCNT; @@ -129,328 +141,494 @@ extern INT32 giFlashContractBaseTime; extern UINT32 guiFlashCursorBaseTime; extern INT32 giPotCharPathBaseTime; -typedef void (*TIMER_NOTIFY_CALLBACK) ( INT32 timer, PTR state ); -struct TIMER_NOTIFY_ITEM -{ - TIMER_NOTIFY_CALLBACK callback; - PTR state; -}; -typedef std::list TIMER_NOTIFY_ITEM_LIST; -typedef TIMER_NOTIFY_ITEM_LIST::iterator TIMER_NOTIFY_ITEM_ITERATOR; -static TIMER_NOTIFY_ITEM_LIST glNotifyCallbacks; -static CRITICAL_SECTION gcsNotifyLock; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + typedef void (*TIMER_NOTIFY_CALLBACK) ( INT32 timer, PTR state ); + struct TIMER_NOTIFY_ITEM + { + TIMER_NOTIFY_CALLBACK callback; + PTR state; + }; + typedef std::list TIMER_NOTIFY_ITEM_LIST; + typedef TIMER_NOTIFY_ITEM_LIST::iterator TIMER_NOTIFY_ITEM_ITERATOR; + static TIMER_NOTIFY_ITEM_LIST glNotifyCallbacks; + static CRITICAL_SECTION gcsNotifyLock; -static bool HasTimerNotifyCallbacks( ); -static void BroadcastTimerNotify(INT32 ); -static BOOLEAN UpdateTimeCounter( INT32 &counter, INT32 &iTimeLeft ); -static BOOLEAN UpdateCounter( INT32 counter, INT32 &iTimeLeft); -static void UpdateTimer(); + static bool HasTimerNotifyCallbacks( ); + static void BroadcastTimerNotify(INT32 ); + static BOOLEAN UpdateTimeCounter( INT32 &counter, INT32 &iTimeLeft ); + static BOOLEAN UpdateCounter( INT32 counter, INT32 &iTimeLeft); + static void UpdateTimer(); +#endif UINT32 InitializeJA2TimerCallback( UINT32 uiDelay, LPTIMECALLBACK TimerProc, UINT32 uiUser ); // CALLBACKS void CALLBACK FlashItem( UINT uiID, UINT uiMsg, DWORD uiUser, DWORD uiDw1, DWORD uiDw2 ); -void CALLBACK TimeProc( UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2 ) -{ - static BOOLEAN fInFunction = FALSE; - //SOLDIERTYPE *pSoldier; - - if ( !fInFunction ) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + void CALLBACK TimeProc( UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2 ) { - fInFunction = TRUE; + static BOOLEAN fInFunction = FALSE; + //SOLDIERTYPE *pSoldier; - BOOLEAN timerDone = FALSE; - BOOLEAN tickTime = FALSE; - INT32 iTimeLeft = 0; - - // Use QPC to check if BASETIMESLICE (in ms) has passed - if (IsHiSpeedClockMode()) + if ( !fInFunction ) { - // Only advance time when sufficient time has passed to exceed next time - QueryPerformanceCounter(&gliPerfCount); - if (gliPerfCount.QuadPart > gliPerfCountNext.QuadPart) + fInFunction = TRUE; + + BOOLEAN timerDone = FALSE; + BOOLEAN tickTime = FALSE; + INT32 iTimeLeft = 0; + + // Use QPC to check if BASETIMESLICE (in ms) has passed + if (IsHiSpeedClockMode()) { - INT32 iNext = IsFastForwardMode() ? giFastForwardPeriod : UPDATETIMESLICE; - gliPerfCountNext.QuadPart = gliPerfCount.QuadPart + (iNext * gliPerfFreq.QuadPart) / FREQUENCY_CONST; - iTimeLeft = iNext; - timerDone = IsFastForwardMode(); - tickTime = TRUE; + // Only advance time when sufficient time has passed to exceed next time + QueryPerformanceCounter(&gliPerfCount); + if (gliPerfCount.QuadPart > gliPerfCountNext.QuadPart) + { + INT32 iNext = IsFastForwardMode() ? giFastForwardPeriod : UPDATETIMESLICE; + gliPerfCountNext.QuadPart = gliPerfCount.QuadPart + (iNext * gliPerfFreq.QuadPart) / FREQUENCY_CONST; + iTimeLeft = iNext; + timerDone = IsFastForwardMode(); + tickTime = TRUE; + } } + else + { + // When using millisecond timer, advance time everytime this function is called + tickTime = TRUE; + timerDone = !IsFastForwardMode(); + } + if (tickTime) + { + guiBaseJA2NoPauseClock += BASETIMESLICE; + + if ( !gfPauseClock ) + { + guiBaseJA2Clock += BASETIMESLICE; + + for ( gCNT = 0; gCNT < NUMTIMERS; gCNT++ ) + { + timerDone |= UpdateCounter( gCNT, iTimeLeft ); + } + + // Update some specialized countdown timers... + timerDone |= UpdateTimeCounter( giTimerAirRaidQuote, iTimeLeft ); + timerDone |= UpdateTimeCounter( giTimerAirRaidDiveStarted, iTimeLeft ); + timerDone |= UpdateTimeCounter( giTimerAirRaidUpdate, iTimeLeft ); + timerDone |= UpdateTimeCounter( giTimerTeamTurnUpdate, iTimeLeft ); + + if ( gpCustomizableTimerCallback ) + { + timerDone |= UpdateTimeCounter( giTimerCustomizable, iTimeLeft ); + } + + #ifndef BOUNDS_CHECKER + + // If mapscreen... + if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) + { + // IN Mapscreen, loop through player's team..... + for ( gCNT = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; gCNT <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; gCNT++ ) + { + gPSOLDIER = MercPtrs[ gCNT ]; + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PortraitFlashCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PanelAnimateCounter, iTimeLeft ); + } + } + else + { + // Set update flags for soldiers + //////////////////////////// + for ( gCNT = 0; gCNT < guiNumMercSlots; gCNT++ ) + { + gPSOLDIER = MercSlots[ gCNT ]; + + if ( gPSOLDIER != NULL ) + { + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.UpdateCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.DamageCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.ReloadCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.FlashSelCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.BlinkSelCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PortraitFlashCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.AICounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.FadeCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.NextTileCounter, iTimeLeft ); + timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PanelAnimateCounter, iTimeLeft ); + #ifdef JA2UB + timerDone |= UpdateTimeCounter( gPSOLDIER->GetupFromJA25StartCounter, iTimeLeft ); + #endif + } + } + } + #endif + } + } + + if (timerDone) + SetEvent(ghNotifyThreadEvent); + fInFunction = FALSE; } - else - { - // When using millisecond timer, advance time everytime this function is called - tickTime = TRUE; - timerDone = !IsFastForwardMode(); - } - if (tickTime) + } +#else + void CALLBACK TimeProc( UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2 ) + { + static BOOLEAN fInFunction = FALSE; + //SOLDIERTYPE *pSoldier; + + if ( !fInFunction ) { + fInFunction = TRUE; + guiBaseJA2NoPauseClock += BASETIMESLICE; + if ( !gfPauseClock ) { guiBaseJA2Clock += BASETIMESLICE; for ( gCNT = 0; gCNT < NUMTIMERS; gCNT++ ) { - timerDone |= UpdateCounter( gCNT, iTimeLeft ); + UPDATECOUNTER( gCNT ); } // Update some specialized countdown timers... - timerDone |= UpdateTimeCounter( giTimerAirRaidQuote, iTimeLeft ); - timerDone |= UpdateTimeCounter( giTimerAirRaidDiveStarted, iTimeLeft ); - timerDone |= UpdateTimeCounter( giTimerAirRaidUpdate, iTimeLeft ); - timerDone |= UpdateTimeCounter( giTimerTeamTurnUpdate, iTimeLeft ); + UPDATETIMECOUNTER( giTimerAirRaidQuote ); + UPDATETIMECOUNTER( giTimerAirRaidDiveStarted ); + UPDATETIMECOUNTER( giTimerAirRaidUpdate ); + UPDATETIMECOUNTER( giTimerTeamTurnUpdate ); if ( gpCustomizableTimerCallback ) { - timerDone |= UpdateTimeCounter( giTimerCustomizable, iTimeLeft ); + UPDATETIMECOUNTER( giTimerCustomizable ); } -#ifndef BOUNDS_CHECKER + #ifndef BOUNDS_CHECKER - // If mapscreen... - if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) + // If mapscreen... + if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) + { + // IN Mapscreen, loop through player's team..... + for ( gCNT = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; gCNT <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; gCNT++ ) { - // IN Mapscreen, loop through player's team..... - for ( gCNT = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; gCNT <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; gCNT++ ) - { - gPSOLDIER = MercPtrs[ gCNT ]; - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PortraitFlashCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PanelAnimateCounter, iTimeLeft ); - } - } - else - { - // Set update flags for soldiers - //////////////////////////// - for ( gCNT = 0; gCNT < guiNumMercSlots; gCNT++ ) - { - gPSOLDIER = MercSlots[ gCNT ]; - - if ( gPSOLDIER != NULL ) - { - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.UpdateCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.DamageCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.ReloadCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.FlashSelCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.BlinkSelCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PortraitFlashCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.AICounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.FadeCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.NextTileCounter, iTimeLeft ); - timerDone |= UpdateTimeCounter( gPSOLDIER->timeCounters.PanelAnimateCounter, iTimeLeft ); -#ifdef JA2UB - timerDone |= UpdateTimeCounter( gPSOLDIER->GetupFromJA25StartCounter, iTimeLeft ); -#endif - } - } - } -#endif + gPSOLDIER = MercPtrs[ gCNT ]; + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.PortraitFlashCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.PanelAnimateCounter ); } + } + else + { + // Set update flags for soldiers + //////////////////////////// + for ( gCNT = 0; gCNT < guiNumMercSlots; gCNT++ ) + { + gPSOLDIER = MercSlots[ gCNT ]; + + if ( gPSOLDIER != NULL ) + { + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.UpdateCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.DamageCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.ReloadCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.FlashSelCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.BlinkSelCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.PortraitFlashCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.AICounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.FadeCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.NextTileCounter ); + UPDATETIMECOUNTER( gPSOLDIER->timeCounters.PanelAnimateCounter ); + #ifdef JA2UB + UPDATETIMECOUNTER( gPSOLDIER->GetupFromJA25StartCounter ); + #endif + } + } + } + #endif + } + + + fInFunction = FALSE; } - - if (timerDone) - SetEvent(ghNotifyThreadEvent); - fInFunction = FALSE; } -} +#endif -static UINT32 MIN_TIMER(UINT32 timer, UINT32 other) -{ - UINT32 value = TIME_MS_TO_US(timer); - return ( value && value < other ? value : other ); -} - -// Returns the smallest time interval for a counter currently in use -UINT32 GetNextCounterDoneTime(void) -{ - QueryPerformanceCounter(&gliPerfCount); - INT32 time = (INT32)(((gliPerfCountNext.QuadPart - gliPerfCount.QuadPart) * FREQUENCY_CONST) / gliPerfFreq.QuadPart); - return (UINT32)((time > 0) ? time : 0); -} - -// Function to test if there are any outstanding timers. Used in fast forward routines -BOOLEAN IsTimerActive(void) -{ - return GetNextCounterDoneTime() <= FASTFORWARDTIMESLICE ? TRUE : FALSE; -} - -DWORD WINAPI JA2ClockThread( LPVOID lpParam ) -{ - __try +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + static UINT32 MIN_TIMER(UINT32 timer, UINT32 other) { + UINT32 value = TIME_MS_TO_US(timer); + return ( value && value < other ? value : other ); + } + + // Returns the smallest time interval for a counter currently in use + UINT32 GetNextCounterDoneTime(void) + { + QueryPerformanceCounter(&gliPerfCount); + INT32 time = (INT32)(((gliPerfCountNext.QuadPart - gliPerfCount.QuadPart) * FREQUENCY_CONST) / gliPerfFreq.QuadPart); + return (UINT32)((time > 0) ? time : 0); + } + + // Function to test if there are any outstanding timers. Used in fast forward routines + BOOLEAN IsTimerActive(void) + { + return GetNextCounterDoneTime() <= FASTFORWARDTIMESLICE ? TRUE : FALSE; + } + + DWORD WINAPI JA2ClockThread( LPVOID lpParam ) + { + __try + { + for(;;) + { + TimeProc(0, 0, 0, 0, 0); + + DWORD dwResult = WaitForSingleObject(ghClockThreadShutdown, 0); + if (dwResult == WAIT_OBJECT_0 || dwResult == WAIT_ABANDONED) + break; + YieldProcessor(); + + // Sleep for a couple of milliseconds if not in fast forward mode + if (!IsFastForwardMode()) + Sleep( TIME_US_TO_MS( GetNextCounterDoneTime() ) ); + } + } + __except( EXCEPTION_EXECUTE_HANDLER ) + { + // Unhandled exception just exit + } + return 0L; + } + + DWORD WINAPI JA2NotifyThread( LPVOID lpParam ) + { + HANDLE waitHandles[] = {ghClockThreadShutdown, ghNotifyThreadEvent}; for(;;) { - TimeProc(0, 0, 0, 0, 0); - DWORD dwResult = WaitForSingleObject(ghClockThreadShutdown, 0); if (dwResult == WAIT_OBJECT_0 || dwResult == WAIT_ABANDONED) break; - YieldProcessor(); - // Sleep for a couple of milliseconds if not in fast forward mode - if (!IsFastForwardMode()) - Sleep( TIME_US_TO_MS( GetNextCounterDoneTime() ) ); - } - } - __except( EXCEPTION_EXECUTE_HANDLER ) - { - // Unhandled exception just exit - } - return 0L; -} - -DWORD WINAPI JA2NotifyThread( LPVOID lpParam ) -{ - HANDLE waitHandles[] = {ghClockThreadShutdown, ghNotifyThreadEvent}; - for(;;) - { - DWORD dwResult = WaitForSingleObject(ghClockThreadShutdown, 0); - if (dwResult == WAIT_OBJECT_0 || dwResult == WAIT_ABANDONED) - break; - - DWORD waitTime = (!IsFastForwardMode()) ? max(TIME_US_TO_MS(MIN_NOTIFY_TIME), TIME_US_TO_MS( GetNextCounterDoneTime() ) ) : 0; - dwResult = WaitForMultipleObjectsEx(_countof(waitHandles), waitHandles, FALSE, waitTime, FALSE); - if (dwResult == WAIT_OBJECT_0) - break; - if (dwResult >= WAIT_ABANDONED_0 && dwResult <= (WAIT_ABANDONED_0 + _countof(waitHandles))) - break; - if ( dwResult == WAIT_FAILED || dwResult == WAIT_TIMEOUT || (dwResult-WAIT_OBJECT_0) == 1) - { - if (HasTimerNotifyCallbacks()) + DWORD waitTime = (!IsFastForwardMode()) ? max(TIME_US_TO_MS(MIN_NOTIFY_TIME), TIME_US_TO_MS( GetNextCounterDoneTime() ) ) : 0; + dwResult = WaitForMultipleObjectsEx(_countof(waitHandles), waitHandles, FALSE, waitTime, FALSE); + if (dwResult == WAIT_OBJECT_0) + break; + if (dwResult >= WAIT_ABANDONED_0 && dwResult <= (WAIT_ABANDONED_0 + _countof(waitHandles))) + break; + if ( dwResult == WAIT_FAILED || dwResult == WAIT_TIMEOUT || (dwResult-WAIT_OBJECT_0) == 1) { - BroadcastTimerNotify(-1); + if (HasTimerNotifyCallbacks()) + { + BroadcastTimerNotify(-1); + } + } + else + { + // unexpected failure + } + } + SetEvent(ghNotifyThreadShutdownComplete); + return 0L; + } +#endif + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + BOOLEAN InitializeJA2Clock() + { + #ifdef CALLBACKTIMER + MMRESULT mmResult; + INT32 cnt; + + // Init timer delays + for ( cnt = 0; cnt < NUMTIMERS; cnt++ ) + { + giTimerCounters[ cnt ] = giTimerIntervals[ cnt ]; + } + + + // First get timer resolutions + mmResult = timeGetDevCaps( >c, sizeof( gtc ) ); + + if ( mmResult != TIMERR_NOERROR ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); + } + + if ( !QueryPerformanceFrequency(&gliPerfFreq) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get performance frequency"); + } + if ( !QueryPerformanceCounter(&gliPerfCount) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get performance frequency"); + } + + timeBeginPeriod(gtc.wPeriodMin); + + InitializeCriticalSection(&gcsNotifyLock); + + if (IsHiSpeedClockMode()) + { + ghClockThreadShutdown = CreateEvent(NULL, TRUE, FALSE, NULL); + ghNotifyThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + ghNotifyThreadShutdownComplete = CreateEvent(NULL, TRUE, FALSE, NULL); + ghClockThread = CreateThread( + NULL, // default security attributes + 0, // use default stack size + JA2ClockThread, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &gdwClockThreadId);// returns the thread identifier + ghNotifyThread = CreateThread( + NULL, // default security attributes + 0, // use default stack size + JA2NotifyThread, // thread function + NULL, // argument to thread function + 0, // use default creation flags + &gdwNotifyThreadId);// returns the thread identifier + } + else + { + UpdateTimer(); + } + #endif + + return TRUE; + } +#else + BOOLEAN InitializeJA2Clock(void) + { + + #ifdef CALLBACKTIMER + + + MMRESULT mmResult; + TIMECAPS tc; + INT32 cnt; + + // Init timer delays + for ( cnt = 0; cnt < NUMTIMERS; cnt++ ) + { + giTimerCounters[ cnt ] = giTimerIntervals[ cnt ]; + } + + + // First get timer resolutions + mmResult = timeGetDevCaps( &tc, sizeof( tc ) ); + + if ( mmResult != TIMERR_NOERROR ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); + } + + // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first + gTimerID = timeSetEvent( BASETIMESLICE, BASETIMESLICE, TimeProc, (DWORD)0, TIME_PERIODIC ); + + if ( !gTimerID ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + } + + #endif + + return TRUE; + } +#endif + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + void ShutdownJA2Clock(void) + { + if (IsHiSpeedClockMode()) + { + SetEvent(ghClockThreadShutdown); + WaitForSingleObject(ghNotifyThreadShutdownComplete, 2000); + HANDLE waitHandles[] = {ghClockThread, ghNotifyThread}; + WaitForMultipleObjects(_countof(waitHandles), waitHandles, TRUE, 1000); + CloseHandle(ghClockThreadShutdown); + CloseHandle(ghClockThread); + CloseHandle(ghNotifyThreadEvent); + CloseHandle(ghNotifyThread); + // During ungraceful shutdowns notify lock may be in use in notify thread + if (TryEnterCriticalSection(&gcsNotifyLock)) + { + LeaveCriticalSection(&gcsNotifyLock); + DeleteCriticalSection(&gcsNotifyLock); } } else { - // unexpected failure + // Make sure we kill the timer + #ifdef CALLBACKTIMER + timeKillEvent( gTimerID ); + #endif } - } - SetEvent(ghNotifyThreadShutdownComplete); - return 0L; -} -BOOLEAN InitializeJA2Clock() -{ -#ifdef CALLBACKTIMER - MMRESULT mmResult; - INT32 cnt; - - // Init timer delays - for ( cnt = 0; cnt < NUMTIMERS; cnt++ ) - { - giTimerCounters[ cnt ] = giTimerIntervals[ cnt ]; + timeEndPeriod(gtc.wPeriodMin); } - - - // First get timer resolutions - mmResult = timeGetDevCaps( >c, sizeof( gtc ) ); - - if ( mmResult != TIMERR_NOERROR ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); - } - - if ( !QueryPerformanceFrequency(&gliPerfFreq) ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get performance frequency"); - } - if ( !QueryPerformanceCounter(&gliPerfCount) ) - { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get performance frequency"); - } - - timeBeginPeriod(gtc.wPeriodMin); - - InitializeCriticalSection(&gcsNotifyLock); - - if (IsHiSpeedClockMode()) - { - ghClockThreadShutdown = CreateEvent(NULL, TRUE, FALSE, NULL); - ghNotifyThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - ghNotifyThreadShutdownComplete = CreateEvent(NULL, TRUE, FALSE, NULL); - ghClockThread = CreateThread( - NULL, // default security attributes - 0, // use default stack size - JA2ClockThread, // thread function - NULL, // argument to thread function - 0, // use default creation flags - &gdwClockThreadId);// returns the thread identifier - ghNotifyThread = CreateThread( - NULL, // default security attributes - 0, // use default stack size - JA2NotifyThread, // thread function - NULL, // argument to thread function - 0, // use default creation flags - &gdwNotifyThreadId);// returns the thread identifier - } - else - { - UpdateTimer(); - } -#endif - - return TRUE; -} - -void ShutdownJA2Clock(void) -{ - if (IsHiSpeedClockMode()) - { - SetEvent(ghClockThreadShutdown); - WaitForSingleObject(ghNotifyThreadShutdownComplete, 2000); - HANDLE waitHandles[] = {ghClockThread, ghNotifyThread}; - WaitForMultipleObjects(_countof(waitHandles), waitHandles, TRUE, 1000); - CloseHandle(ghClockThreadShutdown); - CloseHandle(ghClockThread); - CloseHandle(ghNotifyThreadEvent); - CloseHandle(ghNotifyThread); - // During ungraceful shutdowns notify lock may be in use in notify thread - if (TryEnterCriticalSection(&gcsNotifyLock)) - { - LeaveCriticalSection(&gcsNotifyLock); - DeleteCriticalSection(&gcsNotifyLock); - } - } - else +#else + void ShutdownJA2Clock(void) { // Make sure we kill the timer -#ifdef CALLBACKTIMER + #ifdef CALLBACKTIMER + timeKillEvent( gTimerID ); + + #endif + + } #endif - } - timeEndPeriod(gtc.wPeriodMin); -} - - -UINT32 InitializeJA2TimerCallback( UINT32 uiDelay, LPTIMECALLBACK TimerProc, UINT32 uiUser ) -{ - MMRESULT mmResult; - MMRESULT TimerID; - - - // First get timer resolutions - mmResult = timeGetDevCaps( >c, sizeof( gtc ) ); - - if ( mmResult != TIMERR_NOERROR ) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + UINT32 InitializeJA2TimerCallback( UINT32 uiDelay, LPTIMECALLBACK TimerProc, UINT32 uiUser ) { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); + MMRESULT mmResult; + MMRESULT TimerID; + + + // First get timer resolutions + mmResult = timeGetDevCaps( >c, sizeof( gtc ) ); + + if ( mmResult != TIMERR_NOERROR ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); + } + + // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first + TimerID = timeSetEvent( (UINT)uiDelay, (UINT)uiDelay, TimerProc, (DWORD)uiUser, TIME_PERIODIC ); + + if ( !TimerID ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + } + + return ( (UINT32)TimerID ); } - - // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first - TimerID = timeSetEvent( (UINT)uiDelay, (UINT)uiDelay, TimerProc, (DWORD)uiUser, TIME_PERIODIC ); - - if ( !TimerID ) +#else + UINT32 InitializeJA2TimerCallback( UINT32 uiDelay, LPTIMECALLBACK TimerProc, UINT32 uiUser ) { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + MMRESULT mmResult; + TIMECAPS tc; + MMRESULT TimerID; + + + // First get timer resolutions + mmResult = timeGetDevCaps( &tc, sizeof( tc ) ); + + if ( mmResult != TIMERR_NOERROR ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not get timer properties"); + } + + // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first + TimerID = timeSetEvent( (UINT)uiDelay, (UINT)uiDelay, TimerProc, (DWORD)uiUser, TIME_PERIODIC ); + + if ( !TimerID ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + } + + return ( (UINT32)TimerID ); } - return ( (UINT32)TimerID ); -} +#endif void RemoveJA2TimerCallback( UINT32 uiTimer ) @@ -550,237 +728,241 @@ void SetTileAnimCounter( INT32 iTime ) { giTimerIntervals[ ANIMATETILES ] = iTime; } -void SetFastForwardPeriod(DOUBLE value) -{ - giFastForwardPeriod = (UINT32)(value); - if (giFastForwardPeriod <= 1) - giFastForwardPeriod = 1; -} -void SetFastForwardKey(INT32 key) -{ - giFastForwardKey = key; -} -BOOLEAN IsFastForwardKeyPressed() -{ - // WANNE: In a multiplayer game it is not allowed for the "pure" client to do fast forward - // Only the server is allowed to do, because the AI is generated on the server - if (is_networked) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + void SetFastForwardPeriod(DOUBLE value) { - if (!is_server) // It is not allowed when we are not the server - return false; - else if (gTacticalStatus.ubCurrentTeam != 1) // It is not allowed, when it is not the enemy turn! - return false; + giFastForwardPeriod = (UINT32)(value); + if (giFastForwardPeriod <= 1) + giFastForwardPeriod = 1; } - return giFastForwardKey && IsKeyPressed(giFastForwardKey); -} + void SetFastForwardKey(INT32 key) + { + giFastForwardKey = key; + } -void SetFastForwardMode(BOOLEAN enable) -{ - giFastForwardMode = enable; - UpdateTimer(); -} + BOOLEAN IsFastForwardKeyPressed() + { + // WANNE: In a multiplayer game it is not allowed for the "pure" client to do fast forward + // Only the server is allowed to do, because the AI is generated on the server + if (is_networked) + { + if (!is_server) // It is not allowed when we are not the server + return false; + else if (gTacticalStatus.ubCurrentTeam != 1) // It is not allowed, when it is not the enemy turn! + return false; + } -BOOLEAN IsFastForwardMode() -{ - return giFastForwardMode || IsFastForwardKeyPressed(); -} + return giFastForwardKey && IsKeyPressed(giFastForwardKey); + } -LONGLONG GetJA2Microseconds() -{ - return gliPerfCount.QuadPart * FREQUENCY_CONST / gliPerfFreq.QuadPart; -} + void SetFastForwardMode(BOOLEAN enable) + { + giFastForwardMode = enable; + UpdateTimer(); + } -void AddTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ) -{ - EnterCriticalSection(&gcsNotifyLock); - BOOL addItem = TRUE; - for (TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ++itr) { - if ( callback == (*itr).callback && state == (*itr).state ){ - addItem = FALSE; - break; + BOOLEAN IsFastForwardMode() + { + return giFastForwardMode || IsFastForwardKeyPressed(); + } + + LONGLONG GetJA2Microseconds() + { + return gliPerfCount.QuadPart * FREQUENCY_CONST / gliPerfFreq.QuadPart; + } + + void AddTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ) + { + EnterCriticalSection(&gcsNotifyLock); + BOOL addItem = TRUE; + for (TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ++itr) { + if ( callback == (*itr).callback && state == (*itr).state ){ + addItem = FALSE; + break; + } + } + if (addItem) + { + TIMER_NOTIFY_ITEM item; + item.callback = callback; + item.state = state; + glNotifyCallbacks.push_back(item); + } + LeaveCriticalSection(&gcsNotifyLock); + } + + void RemoveTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ) + { + EnterCriticalSection(&gcsNotifyLock); + for ( TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ) + { + if ( callback == (*itr).callback && state == (*itr).state ) + itr = glNotifyCallbacks.erase(itr); + else + ++itr; + } + LeaveCriticalSection(&gcsNotifyLock); + } + + void ClearTimerNotifyCallbacks() + { + // If we cannot get the lock it is likely due to exception while handling notification and we are shutting down + if ( TryEnterCriticalSection(&gcsNotifyLock) ) + { + glNotifyCallbacks.clear(); + LeaveCriticalSection(&gcsNotifyLock); } } - if (addItem) + + static bool HasTimerNotifyCallbacks( ) { - TIMER_NOTIFY_ITEM item; - item.callback = callback; - item.state = state; - glNotifyCallbacks.push_back(item); + return !glNotifyCallbacks.empty(); } - LeaveCriticalSection(&gcsNotifyLock); -} -void RemoveTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ) -{ - EnterCriticalSection(&gcsNotifyLock); - for ( TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ) + + // Call timer notify routine + // Separate the callback notifies with normal try/catch + // as SEH __try/__except are incompatible with C++ exceptions + static void InnerTimerNotify(INT32 timer) { - if ( callback == (*itr).callback && state == (*itr).state ) - itr = glNotifyCallbacks.erase(itr); - else - ++itr; + try + { + for (TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ++itr) + { + if ( NULL != (*itr).callback) + (*itr).callback( timer, (*itr).state ); + } + } + catch (...) {} } - LeaveCriticalSection(&gcsNotifyLock); -} - -void ClearTimerNotifyCallbacks() -{ - // If we cannot get the lock it is likely due to exception while handling notification and we are shutting down - if ( TryEnterCriticalSection(&gcsNotifyLock) ) + static void BroadcastTimerNotify(INT32 timer) { - glNotifyCallbacks.clear(); - LeaveCriticalSection(&gcsNotifyLock); - } -} - -static bool HasTimerNotifyCallbacks( ) -{ - return !glNotifyCallbacks.empty(); -} - - -// Call timer notify routine -// Separate the callback notifies with normal try/catch -// as SEH __try/__except are incompatible with C++ exceptions -static void InnerTimerNotify(INT32 timer) -{ - try - { - for (TIMER_NOTIFY_ITEM_ITERATOR itr = glNotifyCallbacks.begin(); itr != glNotifyCallbacks.end(); ++itr) - { - if ( NULL != (*itr).callback) - (*itr).callback( timer, (*itr).state ); - } - } - catch (...) {} -} -static void BroadcastTimerNotify(INT32 timer) -{ - EnterCriticalSection(&gcsNotifyLock); - __try - { - __try { InnerTimerNotify(timer); } - __except( EXCEPTION_EXECUTE_HANDLER ) - { /* Not sure. exit? */ } - } - __finally - { - LeaveCriticalSection(&gcsNotifyLock); - } -} - -BOOLEAN UpdateTimeCounter( INT32 &counter, INT32 &iTimeLeft) -{ - if (counter == 0) { - return FALSE; - } else if ( ( counter - BASETIMESLICE ) < 0 ) { - counter = 0; - return TRUE; - } else { - counter -= BASETIMESLICE; - if ( counter < iTimeLeft ) - iTimeLeft = counter; - return FALSE; - } - return FALSE; -} - -BOOLEAN UpdateCounter( INT32 counterIdx, INT32 &iTimeLeft ) -{ - INT32& counter = giTimerCounters[ counterIdx ]; - return UpdateTimeCounter(counter, iTimeLeft); -} - -BOOLEAN UpdateCounter( INT32 counterIdx ) -{ - INT32 iDummy = 0; - return UpdateCounter(counterIdx, iDummy); -} - -void ResetCounter(INT32 counterIdx) -{ - giTimerCounters[ counterIdx ] = giTimerIntervals[ counterIdx ]; -} - -BOOLEAN CounterDone(INT32 counterIdx) -{ - return ( giTimerCounters[ counterIdx ] == 0 ) ? TRUE : FALSE; -} - -void ResetTimerCounter(INT32 &timer, INT32 value) -{ - timer = value; -} - -BOOLEAN TimeCounterDone(INT32 timer) -{ - return ( timer == 0 ) ? TRUE : FALSE; -} - -void ZeroTimeCounter(INT32& timer) -{ - timer = 0; -} - -BOOLEAN IsJA2TimerThread() -{ - return (GetCurrentThreadId() == gdwClockThreadId); -} - -#ifndef GetJA2Clock -UINT32 GetJA2Clock() -{ - return guiBaseJA2Clock; -} -#endif - -#ifndef GetJA2NoPauseClock -UINT32 GetJA2NoPauseClock() -{ - return guiBaseJA2NoPauseClock; -} -#endif - -void SetHiSpeedClockMode(BOOLEAN enable) -{ - gfHispeedClockMode = enable; -} - -BOOLEAN IsHiSpeedClockMode() -{ - return gfHispeedClockMode; -} - -void SetNotifyFrequencyKey(INT32 value) -{ - MIN_NOTIFY_TIME = value; -} - -void SetClockSpeedPercent(FLOAT value) -{ - gfClockSpeedPercent = value; - UPDATETIMESLICE = (UINT32)((FLOAT)TIME_MS_TO_US(BASETIMESLICE) * 100.0f / value); - UpdateTimer(); -} - -void UpdateTimer() -{ - // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first - if (!IsHiSpeedClockMode()) - { - UINT uiTimeSlice = giFastForwardMode ? gtc.wPeriodMin : max(gtc.wPeriodMin, TIME_US_TO_MS(UPDATETIMESLICE)); - if (uiTimeSlice != guiTimeSlice) + EnterCriticalSection(&gcsNotifyLock); + __try { - guiTimeSlice = uiTimeSlice; - if (gTimerID != 0) timeKillEvent(gTimerID); - gTimerID = timeSetEvent( uiTimeSlice, uiTimeSlice, TimeProc, (DWORD)0, TIME_PERIODIC ); - if ( !gTimerID ) + __try { InnerTimerNotify(timer); } + __except( EXCEPTION_EXECUTE_HANDLER ) + { /* Not sure. exit? */ } + } + __finally + { + LeaveCriticalSection(&gcsNotifyLock); + } + } + + BOOLEAN UpdateTimeCounter( INT32 &counter, INT32 &iTimeLeft) + { + if (counter == 0) { + return FALSE; + } else if ( ( counter - BASETIMESLICE ) < 0 ) { + counter = 0; + return TRUE; + } else { + counter -= BASETIMESLICE; + if ( counter < iTimeLeft ) + iTimeLeft = counter; + return FALSE; + } + return FALSE; + } + + BOOLEAN UpdateCounter( INT32 counterIdx, INT32 &iTimeLeft ) + { + INT32& counter = giTimerCounters[ counterIdx ]; + return UpdateTimeCounter(counter, iTimeLeft); + } + + BOOLEAN UpdateCounter( INT32 counterIdx ) + { + INT32 iDummy = 0; + return UpdateCounter(counterIdx, iDummy); + } + + void ResetCounter(INT32 counterIdx) + { + giTimerCounters[ counterIdx ] = giTimerIntervals[ counterIdx ]; + } + + BOOLEAN CounterDone(INT32 counterIdx) + { + return ( giTimerCounters[ counterIdx ] == 0 ) ? TRUE : FALSE; + } + + void ResetTimerCounter(INT32 &timer, INT32 value) + { + timer = value; + } + + BOOLEAN TimeCounterDone(INT32 timer) + { + return ( timer == 0 ) ? TRUE : FALSE; + } + + void ZeroTimeCounter(INT32& timer) + { + timer = 0; + } + + BOOLEAN IsJA2TimerThread() + { + return (GetCurrentThreadId() == gdwClockThreadId); + } + + #ifndef GetJA2Clock + UINT32 GetJA2Clock() + { + return guiBaseJA2Clock; + } + #endif + + #ifndef GetJA2NoPauseClock + UINT32 GetJA2NoPauseClock() + { + return guiBaseJA2NoPauseClock; + } + #endif + + void SetHiSpeedClockMode(BOOLEAN enable) + { + gfHispeedClockMode = enable; + } + + BOOLEAN IsHiSpeedClockMode() + { + return gfHispeedClockMode; + } + + void SetNotifyFrequencyKey(INT32 value) + { + MIN_NOTIFY_TIME = value; + } + + void SetClockSpeedPercent(FLOAT value) + { + gfClockSpeedPercent = value; + UPDATETIMESLICE = (UINT32)((FLOAT)TIME_MS_TO_US(BASETIMESLICE) * 100.0f / value); + UpdateTimer(); + } + + void UpdateTimer() + { + // Set timer at lowest resolution. Could use middle of lowest/highest, we'll see how this performs first + if (!IsHiSpeedClockMode()) + { + UINT uiTimeSlice = giFastForwardMode ? gtc.wPeriodMin : max(gtc.wPeriodMin, TIME_US_TO_MS(UPDATETIMESLICE)); + if (uiTimeSlice != guiTimeSlice) { - DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + guiTimeSlice = uiTimeSlice; + if (gTimerID != 0) timeKillEvent(gTimerID); + gTimerID = timeSetEvent( uiTimeSlice, uiTimeSlice, TimeProc, (DWORD)0, TIME_PERIODIC ); + if ( !gTimerID ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Could not create timer callback"); + } } } } -} +#endif diff --git a/Utils/Timer Control.h b/Utils/Timer Control.h index 2cd89303..64c7b63a 100644 --- a/Utils/Timer Control.h +++ b/Utils/Timer Control.h @@ -54,6 +54,13 @@ enum NUMTIMERS }; +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER +#else + // Base resultion of callback timer + #define BASETIMESLICE 10 +#endif + + // TIMER INTERVALS extern INT32 giTimerIntervals[ NUMTIMERS ]; // TIMER COUNTERS @@ -70,7 +77,10 @@ BOOLEAN InitializeJA2Clock( void ); void ShutdownJA2Clock( void ); #define GetJA2Clock() guiBaseJA2Clock -#define GetJA2NoPauseClock() guiBaseJA2NoPauseClock + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + #define GetJA2NoPauseClock() guiBaseJA2NoPauseClock +#endif UINT32 GetPauseJA2Clock( ); @@ -82,49 +92,89 @@ void PauseTime( BOOLEAN fPaused ); void SetCustomizableTimerCallbackAndDelay( INT32 iDelay, CUSTOMIZABLE_TIMER_CALLBACK pCallback, BOOLEAN fReplace ); void CheckCustomizableTimer( void ); -void SetFastForwardPeriod(DOUBLE value); -void SetFastForwardKey(INT32 key); -BOOLEAN IsFastForwardKeyPressed(); -void SetFastForwardMode(BOOLEAN enable); -BOOLEAN IsFastForwardMode(); -INT32 GetFastForwardLoopCount(); -void SetFastForwardLoopCount(INT32 value); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + void SetFastForwardPeriod(DOUBLE value); + void SetFastForwardKey(INT32 key); + BOOLEAN IsFastForwardKeyPressed(); + void SetFastForwardMode(BOOLEAN enable); + BOOLEAN IsFastForwardMode(); + INT32 GetFastForwardLoopCount(); + void SetFastForwardLoopCount(INT32 value); -void SetNotifyFrequencyKey(INT32 value); -void SetClockSpeedPercent(FLOAT value); + void SetNotifyFrequencyKey(INT32 value); + void SetClockSpeedPercent(FLOAT value); -BOOLEAN IsTimerActive(); -BOOLEAN IsJA2TimerThread(); + BOOLEAN IsTimerActive(); + BOOLEAN IsJA2TimerThread(); -BOOLEAN IsHiSpeedClockMode(); -void SetHiSpeedClockMode(BOOLEAN enable); + BOOLEAN IsHiSpeedClockMode(); + void SetHiSpeedClockMode(BOOLEAN enable); +#endif //Don't modify this value extern UINT32 guiBaseJA2Clock; extern UINT32 guiBaseJA2NoPauseClock; extern CUSTOMIZABLE_TIMER_CALLBACK gpCustomizableTimerCallback; -typedef void (*TIMER_NOTIFY_CALLBACK) ( INT32 timer, PTR state ); -void AddTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ); -void RemoveTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ); -void ClearTimerNotifyCallbacks(); + #ifdef USE_HIGHSPEED_GAMELOOP_TIMER + typedef void (*TIMER_NOTIFY_CALLBACK) ( INT32 timer, PTR state ); + void AddTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ); + void RemoveTimerNotifyCallback( TIMER_NOTIFY_CALLBACK callback, PTR state ); + void ClearTimerNotifyCallbacks(); -BOOLEAN UpdateCounter(INT32 iTimer); -void ResetCounter(INT32 iTimer); -BOOLEAN CounterDone(INT32 iTimer); -void ResetTimerCounter(INT32 &timer, INT32 value); -BOOLEAN TimeCounterDone(INT32 timer); -void ZeroTimeCounter(INT32& timer); + BOOLEAN UpdateCounter(INT32 iTimer); + void ResetCounter(INT32 iTimer); + BOOLEAN CounterDone(INT32 iTimer); + void ResetTimerCounter(INT32 &timer, INT32 value); + BOOLEAN TimeCounterDone(INT32 timer); + void ZeroTimeCounter(INT32& timer); -#define UPDATECOUNTER( c ) UpdateCounter(c) -#define RESETCOUNTER( c ) ResetCounter(c) -#define COUNTERDONE( c ) CounterDone(c) -#define UPDATETIMECOUNTER( c ) UpdateTimeCounter(c) -#define RESETTIMECOUNTER( c, d ) ResetTimerCounter(c, d) -#define TIMECOUNTERDONE(c, d) TimeCounterDone(c) -#define SYNCTIMECOUNTER( ) -#define ZEROTIMECOUNTER(c) ZeroTimeCounter(c) + #define UPDATECOUNTER( c ) UpdateCounter(c) + #define RESETCOUNTER( c ) ResetCounter(c) + #define COUNTERDONE( c ) CounterDone(c) + #define UPDATETIMECOUNTER( c ) UpdateTimeCounter(c) + #define RESETTIMECOUNTER( c, d ) ResetTimerCounter(c, d) + #define TIMECOUNTERDONE(c, d) TimeCounterDone(c) + #define SYNCTIMECOUNTER( ) + #define ZEROTIMECOUNTER(c) ZeroTimeCounter(c) +#else + + // MACROS + // CHeck if new counter < 0 | set to 0 | Decrement + + #ifdef CALLBACKTIMER + + #define UPDATECOUNTER( c ) ( ( giTimerCounters[ c ] - BASETIMESLICE ) < 0 ) ? ( giTimerCounters[ c ] = 0 ) : ( giTimerCounters[ c ] -= BASETIMESLICE ) + #define RESETCOUNTER( c ) ( giTimerCounters[ c ] = giTimerIntervals[ c ] ) + #define COUNTERDONE( c ) ( giTimerCounters[ c ] == 0 ) ? TRUE : FALSE + + #define UPDATETIMECOUNTER( c ) ( ( c - BASETIMESLICE ) < 0 ) ? ( c = 0 ) : ( c -= BASETIMESLICE ) + #define RESETTIMECOUNTER( c, d ) ( c = d ) + + #ifdef BOUNDS_CHECKER + #define TIMECOUNTERDONE( c, d ) ( TRUE ) + #else + #define TIMECOUNTERDONE( c, d ) ( c == 0 ) ? TRUE : FALSE + #endif + + #define SYNCTIMECOUNTER( ) + #define ZEROTIMECOUNTER( c ) ( c = 0 ) + + #else + + #define UPDATECOUNTER( c ) + #define RESETCOUNTER( c ) ( giTimerCounters[ c ] = giClockTimer ) + #define COUNTERDONE( c ) ( ( ( giClockTimer = GetJA2Clock() ) - giTimerCounters[ c ] ) > giTimerIntervals[ c ] ) ? TRUE : FALSE + + #define UPDATETIMECOUNTER( c ) + #define RESETTIMECOUNTER( c, d ) ( c = giClockTimer ) + #define TIMECOUNTERDONE( c, d ) ( giClockTimer - c > d ) ? TRUE : FALSE + #define SYNCTIMECOUNTER( ) ( giClockTimer = GetJA2Clock() ) + + #endif + +#endif void SetTileAnimCounter( INT32 iTime ); #endif \ No newline at end of file diff --git a/Utils/Utils All.h b/Utils/Utils All.h index a8ed4673..a5dc1640 100644 --- a/Utils/Utils All.h +++ b/Utils/Utils All.h @@ -103,7 +103,11 @@ #include "vobject.h" #include "overhead types.h" #include "tactical save.h" -#include "KeyMap.h" + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + #include "KeyMap.h" +#endif + //#include //#include //#include diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 75139409..3949cc18 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -5110,7 +5110,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"自动加速敌军回合", // Automatic fast forward through AI turns +#endif + L"Allow Zombies", // TODO.Translate L"--作弊模式选项--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"强制 Bobby Ray 送货", // force all pending Bobby Ray shipments @@ -5219,7 +5223,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", //TODO.Translate L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"打开时,敌军回合将被大幅加速。", +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"强制 Bobby Ray 出货", diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index c0973e37..62dafd81 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -5109,7 +5109,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // TODO.Translate L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments @@ -5218,7 +5222,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", //TODO.Translate L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index c2c79ccc..ac63fe7a 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -5108,7 +5108,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training L"Quiet Repairing", // Madd: mercs don't say quotes while repairing L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments @@ -5217,7 +5221,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", L"When ON, mercs will not report progress during doctoring.", + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", +#endif + L"When ON, zombies will spawn. Be aware!", // allow zombies L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 6f11ae6d..a96fc380 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -5099,7 +5099,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Forcer envois Bobby Ray", // force all pending Bobby Ray shipments @@ -5208,7 +5212,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Forcer tous les envois en attente de Bobby Ray", diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 58a10556..69a8a739 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -4957,7 +4957,11 @@ STR16 zOptionsToggleText[] = L"Stummes Trainieren", // Madd: mercs don't say quotes while training L"Stummes Reparieren", // Madd: mercs don't say quotes while repairing L"Stumme Behandlung", // Madd: mercs don't say quotes while doctoring + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Autom. schnelle Gegner-Züge", // Automatic fast forward through AI turns +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Erzwinge BR Lieferung", // force all pending Bobby Ray shipments @@ -5066,7 +5070,11 @@ STR16 zOptionsScreenHelpText[] = L"Wenn diese Funktion aktiviert ist, werden die Söldner über ihren Fortschritt während des Trainings nicht mehr berichten.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Wenn diese Funktion aktiviert ist, werden gegnerische Züge schneller durchgeführt.", +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 2976ff28..da02cf1b 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -5094,7 +5094,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments @@ -5203,7 +5207,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 6cd735d3..336b67d5 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -5106,7 +5106,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments @@ -5215,7 +5219,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"WymuŚ wszystkie oczekiwane dostawy od Bobby Ray's.", diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 544673a7..6779f607 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -5089,7 +5089,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Читерские настройки--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Ускорить доставку Бобби Рэя", // force all pending Bobby Ray shipments @@ -5198,7 +5202,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Выберите этот пункт чтобы груз Бобби Рэя прибыл немедленно.", diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index 6a33facb..ec73b153 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -5110,7 +5110,11 @@ STR16 zOptionsToggleText[] = L"Quiet Training", // Madd: mercs don't say quotes while training // TODO.Translate L"Quiet Repairing", // Madd: mercs don't say quotes while repairing //TODO.Translate L"Quiet Doctoring", // Madd: mercs don't say quotes while doctoring //TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"Auto Fast Forward AI Turns", // Automatic fast forward through AI turns // TODO.Translate +#endif + L"Allow Zombies", // Flugente Zombies 1.0 L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Force Bobby Ray shipments", // force all pending Bobby Ray shipments @@ -5219,7 +5223,11 @@ STR16 zOptionsScreenHelpText[] = L"When ON, mercs will not report progress during training.", L"When ON, mercs will not report progress during repairing.", // TODO.Translate L"When ON, mercs will not report progress during doctoring.", // TODO.Translate + +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER L"When ON, AI turns will be much faster.", // TODO.Translate +#endif + L"When ON, zombies will span. Be aware!", // allow zombies // TODO.Translate L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", diff --git a/aniviewscreen.cpp b/aniviewscreen.cpp index 55b19ef6..983956ce 100644 --- a/aniviewscreen.cpp +++ b/aniviewscreen.cpp @@ -185,7 +185,11 @@ UINT32 AniEditScreenHandle(void) } +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER if (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + if (DequeueEvent(&InputEvent) == TRUE) +#endif { if ((InputEvent.usEvent == KEY_DOWN)&&(InputEvent.usParam == ESC)) { diff --git a/builddefines.h b/builddefines.h index 6f72b812..a8ccd5c5 100644 --- a/builddefines.h +++ b/builddefines.h @@ -3,6 +3,11 @@ #include "Language Defines.h" +// WANNE: Enable this define, to build the gameloop with the highspeed timer. To use the highspeed timer, you also have to set the HIGHSPEED_TIMER = TRUE in ja2.ini +// CAUTION: A lot of games reported, when the exe is compiled with the highspeed timer on, the game runs very slowly in strategy map screen when doing repair, .. +// This is the reason, why I made a compilation define, where we can turn on/off the highspeed timer. +//#define USE_HIGHSPEED_GAMELOOP_TIMER + // ----------------------------- // ***************************** // WANNE: Enable those 2 defines, if you want to build UB-Version!! diff --git a/gameloop.cpp b/gameloop.cpp index b9bf2ffc..8adfbe4c 100644 --- a/gameloop.cpp +++ b/gameloop.cpp @@ -148,11 +148,12 @@ BOOLEAN InitializeGame(void) InitButtonSystem(); InitCursors( ); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER SetFastForwardPeriod(gGameExternalOptions.iFastForwardPeriod); SetFastForwardKey(gGameExternalOptions.iFastForwardKey); SetNotifyFrequencyKey(gGameExternalOptions.iNotifyFrequency); SetClockSpeedPercent(gGameExternalOptions.fClockSpeedPercent); - +#endif // Init Fonts if ( !InitializeFonts( ) ) @@ -599,19 +600,21 @@ void NextLoopCheckForEnoughFreeHardDriveSpace() } -// Called by any game loop after all known events were handled -void HandleDefaultEvent(InputAtom *Event) -{ - const int MouseButtonEvents = LEFT_BUTTON_REPEAT|RIGHT_BUTTON_REPEAT| - LEFT_BUTTON_DOWN|LEFT_BUTTON_UP|MIDDLE_BUTTON_UP|X1_BUTTON_UP|X2_BUTTON_UP| - RIGHT_BUTTON_DOWN|RIGHT_BUTTON_UP|MIDDLE_BUTTON_DOWN|X1_BUTTON_DOWN|X2_BUTTON_DOWN| - MOUSE_WHEEL_UP|MOUSE_WHEEL_DOWN; - - if (Event != NULL && Event->usEvent & MouseButtonEvents) +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + // Called by any game loop after all known events were handled + void HandleDefaultEvent(InputAtom *Event) { - POINT MousePos; - GetCursorPos(&MousePos); - ScreenToClient(ghWindow, &MousePos); // In window coords! - MouseSystemHook(Event->usEvent, (UINT16)MousePos.x ,(UINT16)MousePos.y ,_LeftButtonDown, _RightButtonDown); + const int MouseButtonEvents = LEFT_BUTTON_REPEAT|RIGHT_BUTTON_REPEAT| + LEFT_BUTTON_DOWN|LEFT_BUTTON_UP|MIDDLE_BUTTON_UP|X1_BUTTON_UP|X2_BUTTON_UP| + RIGHT_BUTTON_DOWN|RIGHT_BUTTON_UP|MIDDLE_BUTTON_DOWN|X1_BUTTON_DOWN|X2_BUTTON_DOWN| + MOUSE_WHEEL_UP|MOUSE_WHEEL_DOWN; + + if (Event != NULL && Event->usEvent & MouseButtonEvents) + { + POINT MousePos; + GetCursorPos(&MousePos); + ScreenToClient(ghWindow, &MousePos); // In window coords! + MouseSystemHook(Event->usEvent, (UINT16)MousePos.x ,(UINT16)MousePos.y ,_LeftButtonDown, _RightButtonDown); + } } -} +#endif diff --git a/gameloop.h b/gameloop.h index e9ccfbc2..6c5d2357 100644 --- a/gameloop.h +++ b/gameloop.h @@ -18,7 +18,9 @@ void HandleShortCutExitState( void ); void SetPendingNewScreen( UINT32 uiNewScreen ); -struct InputAtom; -void HandleDefaultEvent(InputAtom *Event); +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER + struct InputAtom; + void HandleDefaultEvent(InputAtom *Event); +#endif #endif diff --git a/jascreens.cpp b/jascreens.cpp index 5639d63e..084702ff 100644 --- a/jascreens.cpp +++ b/jascreens.cpp @@ -321,7 +321,11 @@ UINT32 ErrorScreenHandle(void) EndFrameBufferRender( ); // Check for esc +#ifdef USE_HIGHSPEED_GAMELOOP_TIMER while (DequeueSpecificEvent(&InputEvent, KEY_DOWN|KEY_UP|KEY_REPEAT)) +#else + while (DequeueEvent(&InputEvent) == TRUE) +#endif { if( InputEvent.usEvent == KEY_DOWN ) {