From 9706462752737ad8b77c87e5bac9a892c255f62b Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 11 Nov 2025 18:27:29 -0500 Subject: [PATCH 01/30] Fix middle mouse button click detection to use real-time instead of frames --- .../Code/GameEngine/Include/GameClient/LookAtXlat.h | 2 +- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 12 ++++++------ .../Code/GameEngine/Include/GameClient/LookAtXlat.h | 2 +- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h index 91522d87b1a..0ec0645f905 100644 --- a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -76,7 +76,7 @@ class LookAtTranslator : public GameMessageTranslator Bool m_isRotating; // set to true if we are in the act of MMB rotating Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation Bool m_isChangingFOV; // set to true if we are in the act of changing the field of view - UnsignedInt m_timestamp; // set when button goes down + UnsignedInt m_middleButtonDownTimeMS; // real-time in milliseconds when middle button goes down DrawableID m_lastPlaneID; ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 1f0d4e7cc7a..403b6eee898 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -137,7 +137,7 @@ LookAtTranslator::LookAtTranslator() : m_isRotating(false), m_isPitching(false), m_isChangingFOV(false), - m_timestamp(0), + m_middleButtonDownTimeMS(0), m_lastPlaneID(INVALID_DRAWABLE_ID), m_lastMouseMoveFrame(0), m_scrollType(SCROLL_NONE) @@ -278,8 +278,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { stopScrolling(); } - break; - } + break; + } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: @@ -291,7 +291,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_timestamp = TheGameClient->getFrame(); + m_middleButtonDownTimeMS = timeGetTime(); break; } @@ -300,7 +300,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { m_lastMouseMoveFrame = TheGameLogic->getFrame(); - const UnsignedInt CLICK_DURATION = 5; + const UnsignedInt CLICK_DURATION_MS = 167; const UnsignedInt PIXEL_OFFSET = 5; m_isRotating = false; @@ -309,7 +309,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && TheGameClient->getFrame() - m_timestamp < CLICK_DURATION) + if (!didMove && timeGetTime() - m_middleButtonDownTimeMS < CLICK_DURATION_MS) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h index e91b98f66ec..f414320d979 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -76,7 +76,7 @@ class LookAtTranslator : public GameMessageTranslator Bool m_isRotating; // set to true if we are in the act of MMB rotating Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation Bool m_isChangingFOV; // set to true if we are in the act of changing the field of view - UnsignedInt m_timestamp; // set when button goes down + UnsignedInt m_middleButtonDownTimeMS; // real-time in milliseconds when middle button goes down DrawableID m_lastPlaneID; ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 8d900a3636e..4024b4411b6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -137,7 +137,7 @@ LookAtTranslator::LookAtTranslator() : m_isRotating(false), m_isPitching(false), m_isChangingFOV(false), - m_timestamp(0), + m_middleButtonDownTimeMS(0), m_lastPlaneID(INVALID_DRAWABLE_ID), m_lastMouseMoveFrame(0), m_scrollType(SCROLL_NONE) @@ -277,8 +277,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { stopScrolling(); } - break; - } + break; + } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: @@ -290,7 +290,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_timestamp = TheGameClient->getFrame(); + m_middleButtonDownTimeMS = timeGetTime(); break; } @@ -299,7 +299,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { m_lastMouseMoveFrame = TheGameLogic->getFrame(); - const UnsignedInt CLICK_DURATION = 5; + const UnsignedInt CLICK_DURATION_MS = 167; const UnsignedInt PIXEL_OFFSET = 5; m_isRotating = false; @@ -308,7 +308,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && TheGameClient->getFrame() - m_timestamp < CLICK_DURATION) + if (!didMove && timeGetTime() - m_middleButtonDownTimeMS < CLICK_DURATION_MS) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); From 899a8efd757508f5e98dc12788e4028e21630b30 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Tue, 11 Nov 2025 18:27:30 -0500 Subject: [PATCH 02/30] Fix keyboard repeat delay to use real-time instead of frames --- .../Code/GameEngine/Include/GameClient/Keyboard.h | 3 ++- .../Source/GameClient/Input/Keyboard.cpp | 14 +++++++++++--- .../Code/GameEngine/Include/GameClient/Keyboard.h | 3 ++- .../Source/GameClient/Input/Keyboard.cpp | 14 +++++++++++--- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index e4ee92bf495..39f9687690c 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -77,6 +77,7 @@ struct KeyboardIO UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h UnsignedInt sequence; // sequence info from DirectX used for order + UnsignedInt keyDownTimeMS; // real-time in milliseconds when key went down }; @@ -86,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY = 10 }; + enum { KEY_REPEAT_DELAY_MS = 333 }; public: diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 5eb6a69ccec..b6eb5ebd70d 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -142,6 +142,12 @@ void Keyboard::updateKeys( void ) m_keyStatus[ m_keys[ index ].key ].status = m_keys[ index ].status; m_keyStatus[ m_keys[ index ].key ].sequence = m_inputFrame; + // Update key down time for new key presses + if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) + { + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMS = timeGetTime(); + } + // prevent ALT-TAB from causing a TAB event if( m_keys[ index ].key == KEY_TAB ) { @@ -214,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat + UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( (m_inputFrame - m_keyStatus[ key ].sequence) > Keyboard::KEY_REPEAT_DELAY ) + if( now - m_keyStatus[ key ].keyDownTimeMS > Keyboard::KEY_REPEAT_DELAY_MS ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -234,8 +241,9 @@ Bool Keyboard::checkKeyRepeat( void ) for( index = 0; index< NUM_KEYS; index++ ) m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again in two frames - m_keyStatus[ key ].sequence = m_inputFrame - (Keyboard::KEY_REPEAT_DELAY + 2); + // Set repeated key so it will repeat again after a short interval + const UnsignedInt KEY_REPEAT_INTERVAL_MS = 67; // ~2 frames at 30 FPS + m_keyStatus[ key ].keyDownTimeMS = now - (Keyboard::KEY_REPEAT_DELAY_MS - KEY_REPEAT_INTERVAL_MS); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index fa54abe2265..6eac45ea6ba 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -77,6 +77,7 @@ struct KeyboardIO UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h UnsignedInt sequence; // sequence info from DirectX used for order + UnsignedInt keyDownTimeMS; // real-time in milliseconds when key went down }; @@ -86,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY = 10 }; + enum { KEY_REPEAT_DELAY_MS = 333 }; public: diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index bb151a18d78..6cda67e5b67 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -142,6 +142,12 @@ void Keyboard::updateKeys( void ) m_keyStatus[ m_keys[ index ].key ].status = m_keys[ index ].status; m_keyStatus[ m_keys[ index ].key ].sequence = m_inputFrame; + // Update key down time for new key presses + if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) + { + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMS = timeGetTime(); + } + // prevent ALT-TAB from causing a TAB event if( m_keys[ index ].key == KEY_TAB ) { @@ -214,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat + UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( (m_inputFrame - m_keyStatus[ key ].sequence) > Keyboard::KEY_REPEAT_DELAY ) + if( now - m_keyStatus[ key ].keyDownTimeMS > Keyboard::KEY_REPEAT_DELAY_MS ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -234,8 +241,9 @@ Bool Keyboard::checkKeyRepeat( void ) for( index = 0; index< NUM_KEYS; index++ ) m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again in two frames - m_keyStatus[ key ].sequence = m_inputFrame - (Keyboard::KEY_REPEAT_DELAY + 2); + // Set repeated key so it will repeat again after a short interval + const UnsignedInt KEY_REPEAT_INTERVAL_MS = 67; // ~2 frames at 30 FPS + m_keyStatus[ key ].keyDownTimeMS = now - (Keyboard::KEY_REPEAT_DELAY_MS - KEY_REPEAT_INTERVAL_MS); retVal = TRUE; break; // exit for key From 1cee0539625be1272a014e097358eebf0d842c6e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 13:40:32 -0500 Subject: [PATCH 03/30] tweak(input): Reduce keyboard repeat delay from 333ms to 250ms for snappier feel --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index 39f9687690c..ce2bff2172a 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MS = 333 }; + enum { KEY_REPEAT_DELAY_MS = 250 }; public: diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 6eac45ea6ba..82afe7c343c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MS = 333 }; + enum { KEY_REPEAT_DELAY_MS = 250 }; public: From 3d504dd627a8f0c9052089dffd331b2fb9114f89 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 21:46:52 -0500 Subject: [PATCH 04/30] refactor(input): Use Msec naming convention for millisecond variables --- .../Code/GameEngine/Include/GameClient/Keyboard.h | 4 ++-- .../Code/GameEngine/Include/GameClient/LookAtXlat.h | 2 +- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 8 ++++---- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 8 ++++---- .../Code/GameEngine/Include/GameClient/Keyboard.h | 4 ++-- .../Code/GameEngine/Include/GameClient/LookAtXlat.h | 2 +- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 13 +++++++++---- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 8 ++++---- 8 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index ce2bff2172a..e17315d7ed5 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -77,7 +77,7 @@ struct KeyboardIO UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h UnsignedInt sequence; // sequence info from DirectX used for order - UnsignedInt keyDownTimeMS; // real-time in milliseconds when key went down + UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MS = 250 }; + enum { KEY_REPEAT_DELAY_MSEC = 250 }; public: diff --git a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h index 0ec0645f905..91a3deff5c8 100644 --- a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -76,7 +76,7 @@ class LookAtTranslator : public GameMessageTranslator Bool m_isRotating; // set to true if we are in the act of MMB rotating Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation Bool m_isChangingFOV; // set to true if we are in the act of changing the field of view - UnsignedInt m_middleButtonDownTimeMS; // real-time in milliseconds when middle button goes down + UnsignedInt m_middleButtonDownTimeMsec; // real-time in milliseconds when middle button goes down DrawableID m_lastPlaneID; ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index b6eb5ebd70d..4bbe5755bb7 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -145,7 +145,7 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMS = timeGetTime(); + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); } // prevent ALT-TAB from causing a TAB event @@ -227,7 +227,7 @@ Bool Keyboard::checkKeyRepeat( void ) if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( now - m_keyStatus[ key ].keyDownTimeMS > Keyboard::KEY_REPEAT_DELAY_MS ) + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -242,8 +242,8 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].sequence = m_inputFrame; // Set repeated key so it will repeat again after a short interval - const UnsignedInt KEY_REPEAT_INTERVAL_MS = 67; // ~2 frames at 30 FPS - m_keyStatus[ key ].keyDownTimeMS = now - (Keyboard::KEY_REPEAT_DELAY_MS - KEY_REPEAT_INTERVAL_MS); + const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 403b6eee898..508b33b5d42 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -137,7 +137,7 @@ LookAtTranslator::LookAtTranslator() : m_isRotating(false), m_isPitching(false), m_isChangingFOV(false), - m_middleButtonDownTimeMS(0), + m_middleButtonDownTimeMsec(0), m_lastPlaneID(INVALID_DRAWABLE_ID), m_lastMouseMoveFrame(0), m_scrollType(SCROLL_NONE) @@ -291,7 +291,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMS = timeGetTime(); + m_middleButtonDownTimeMsec = timeGetTime(); break; } @@ -300,7 +300,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { m_lastMouseMoveFrame = TheGameLogic->getFrame(); - const UnsignedInt CLICK_DURATION_MS = 167; + const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; m_isRotating = false; @@ -309,7 +309,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && timeGetTime() - m_middleButtonDownTimeMS < CLICK_DURATION_MS) + if (!didMove && timeGetTime() - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 82afe7c343c..2d51dfc8779 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -77,7 +77,7 @@ struct KeyboardIO UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h UnsignedInt sequence; // sequence info from DirectX used for order - UnsignedInt keyDownTimeMS; // real-time in milliseconds when key went down + UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MS = 250 }; + enum { KEY_REPEAT_DELAY_MSEC = 250 }; public: diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h index f414320d979..303f011c333 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -76,7 +76,7 @@ class LookAtTranslator : public GameMessageTranslator Bool m_isRotating; // set to true if we are in the act of MMB rotating Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation Bool m_isChangingFOV; // set to true if we are in the act of changing the field of view - UnsignedInt m_middleButtonDownTimeMS; // real-time in milliseconds when middle button goes down + UnsignedInt m_middleButtonDownTimeMsec; // real-time in milliseconds when middle button goes down DrawableID m_lastPlaneID; ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 6cda67e5b67..b8af2a83d6e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -130,6 +130,9 @@ void Keyboard::updateKeys( void ) } while( m_keys[ index++ ].key != KEY_NONE ); + // Get current time once for all key updates + UnsignedInt now = 0; + // update keyboard status array index = 0; while( m_keys[ index ].key != KEY_NONE ) @@ -145,7 +148,9 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMS = timeGetTime(); + if( !now ) + now = timeGetTime(); + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = now; } // prevent ALT-TAB from causing a TAB event @@ -227,7 +232,7 @@ Bool Keyboard::checkKeyRepeat( void ) if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( now - m_keyStatus[ key ].keyDownTimeMS > Keyboard::KEY_REPEAT_DELAY_MS ) + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -242,8 +247,8 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].sequence = m_inputFrame; // Set repeated key so it will repeat again after a short interval - const UnsignedInt KEY_REPEAT_INTERVAL_MS = 67; // ~2 frames at 30 FPS - m_keyStatus[ key ].keyDownTimeMS = now - (Keyboard::KEY_REPEAT_DELAY_MS - KEY_REPEAT_INTERVAL_MS); + const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 4024b4411b6..3064bb3e0af 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -137,7 +137,7 @@ LookAtTranslator::LookAtTranslator() : m_isRotating(false), m_isPitching(false), m_isChangingFOV(false), - m_middleButtonDownTimeMS(0), + m_middleButtonDownTimeMsec(0), m_lastPlaneID(INVALID_DRAWABLE_ID), m_lastMouseMoveFrame(0), m_scrollType(SCROLL_NONE) @@ -290,7 +290,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMS = timeGetTime(); + m_middleButtonDownTimeMsec = timeGetTime(); break; } @@ -299,7 +299,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { m_lastMouseMoveFrame = TheGameLogic->getFrame(); - const UnsignedInt CLICK_DURATION_MS = 167; + const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; m_isRotating = false; @@ -308,7 +308,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && timeGetTime() - m_middleButtonDownTimeMS < CLICK_DURATION_MS) + if (!didMove && timeGetTime() - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); From 94fa484ca74b918685befbd9d9a08840b401370b Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 21:48:41 -0500 Subject: [PATCH 05/30] perf(input): Reduce timeGetTime() calls in keyboard input processing --- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 4bbe5755bb7..b125b386dce 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -130,6 +130,9 @@ void Keyboard::updateKeys( void ) } while( m_keys[ index++ ].key != KEY_NONE ); + // Get current time once for all key updates + UnsignedInt now = 0; + // update keyboard status array index = 0; while( m_keys[ index ].key != KEY_NONE ) @@ -145,7 +148,9 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); + if( !now ) + now = timeGetTime(); + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = now; } // prevent ALT-TAB from causing a TAB event From 7de0c1b7f879f1c14b0bd41278b75598a169304d Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 21:55:48 -0500 Subject: [PATCH 06/30] refactor(input): Move KEY_REPEAT_INTERVAL_MSEC constant to improve code clarity --- Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 4 ++-- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index b125b386dce..750f76cbd3c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -225,6 +225,7 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat + const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { @@ -246,8 +247,7 @@ Bool Keyboard::checkKeyRepeat( void ) for( index = 0; index< NUM_KEYS; index++ ) m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again after a short interval - const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + // Set repeated key so it will repeat again after the interval m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index b8af2a83d6e..534843c807b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -225,6 +225,7 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat + const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { @@ -246,8 +247,7 @@ Bool Keyboard::checkKeyRepeat( void ) for( index = 0; index< NUM_KEYS; index++ ) m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again after a short interval - const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + // Set repeated key so it will repeat again after the interval m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; From 86d31f4a77b5be12cdb26f40d8fdf0c225439f7b Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 21:56:48 -0500 Subject: [PATCH 07/30] docs(input): Clarify sequence field usage in KeyboardIO struct --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index e17315d7ed5..2a2ca0053ba 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -76,7 +76,7 @@ struct KeyboardIO UnsignedByte key; // KeyDefType, key data UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h - UnsignedInt sequence; // sequence info from DirectX used for order + UnsignedInt sequence; // DirectInput sequence number; overwritten with frame number for ordering UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 2d51dfc8779..0b5e26cbd2d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -76,7 +76,7 @@ struct KeyboardIO UnsignedByte key; // KeyDefType, key data UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h - UnsignedInt sequence; // sequence info from DirectX used for order + UnsignedInt sequence; // DirectInput sequence number; overwritten with frame number for ordering UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; From ad295cc54e1b2b3576d54f3d39b0767fe7d13f81 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 22:07:54 -0500 Subject: [PATCH 08/30] refactor(input): Convert mouse movement tracking from frames to real-time --- .../Include/GameClient/LookAtXlat.h | 2 +- .../GameClient/MessageStream/LookAtXlat.cpp | 24 +++++++++++-------- .../Include/GameClient/LookAtXlat.h | 2 +- .../GameClient/MessageStream/LookAtXlat.cpp | 24 +++++++++++-------- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h index 91a3deff5c8..619f9bea85e 100644 --- a/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -81,7 +81,7 @@ class LookAtTranslator : public GameMessageTranslator ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; ScreenEdgeScrollMode m_screenEdgeScrollMode; - UnsignedInt m_lastMouseMoveFrame; + UnsignedInt m_lastMouseMoveTimeMsec; // real-time in milliseconds when mouse last moved void setScrolling( ScrollType scrollType ); void stopScrolling( void ); diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 508b33b5d42..00590a35642 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -139,7 +139,7 @@ LookAtTranslator::LookAtTranslator() : m_isChangingFOV(false), m_middleButtonDownTimeMsec(0), m_lastPlaneID(INVALID_DRAWABLE_ID), - m_lastMouseMoveFrame(0), + m_lastMouseMoveTimeMsec(0), m_scrollType(SCROLL_NONE) { m_anchor.x = m_anchor.y = 0; @@ -171,10 +171,14 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - if (m_lastMouseMoveFrame > TheGameLogic->getFrame()) - m_lastMouseMoveFrame = 0; // reset for new game + const UnsignedInt ONE_SECOND_MSEC = 1000; + UnsignedInt now = timeGetTime(); - if (m_lastMouseMoveFrame + LOGICFRAMES_PER_SECOND < TheGameLogic->getFrame()) + // Handle time wraparound + if (now < m_lastMouseMoveTimeMsec) + m_lastMouseMoveTimeMsec = now; + + if (now - m_lastMouseMoveTimeMsec > ONE_SECOND_MSEC) return false; return true; @@ -256,7 +260,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_anchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; @@ -272,7 +276,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_UP: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); if (m_scrollType == SCROLL_RMB) { @@ -284,7 +288,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; @@ -298,7 +302,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; @@ -322,7 +326,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage case GameMessage::MSG_RAW_MOUSE_POSITION: { if (m_currentPos.x != msg->getArgument( 0 )->pixel.x || m_currentPos.y != msg->getArgument( 0 )->pixel.y) - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_currentPos = msg->getArgument( 0 )->pixel; @@ -402,7 +406,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_WHEEL: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); Int spin = msg->getArgument( 1 )->integer; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h index 303f011c333..db162de3ede 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/LookAtXlat.h @@ -81,7 +81,7 @@ class LookAtTranslator : public GameMessageTranslator ViewLocation m_viewLocation[ MAX_VIEW_LOCS ]; ScrollType m_scrollType; ScreenEdgeScrollMode m_screenEdgeScrollMode; - UnsignedInt m_lastMouseMoveFrame; + UnsignedInt m_lastMouseMoveTimeMsec; // real-time in milliseconds when mouse last moved void setScrolling( ScrollType scrollType ); void stopScrolling( void ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 3064bb3e0af..c20e6232601 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -139,7 +139,7 @@ LookAtTranslator::LookAtTranslator() : m_isChangingFOV(false), m_middleButtonDownTimeMsec(0), m_lastPlaneID(INVALID_DRAWABLE_ID), - m_lastMouseMoveFrame(0), + m_lastMouseMoveTimeMsec(0), m_scrollType(SCROLL_NONE) { m_anchor.x = m_anchor.y = 0; @@ -171,10 +171,14 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - if (m_lastMouseMoveFrame > TheGameLogic->getFrame()) - m_lastMouseMoveFrame = 0; // reset for new game + const UnsignedInt ONE_SECOND_MSEC = 1000; + UnsignedInt now = timeGetTime(); - if (m_lastMouseMoveFrame + LOGICFRAMES_PER_SECOND < TheGameLogic->getFrame()) + // Handle time wraparound + if (now < m_lastMouseMoveTimeMsec) + m_lastMouseMoveTimeMsec = now; + + if (now - m_lastMouseMoveTimeMsec > ONE_SECOND_MSEC) return false; return true; @@ -256,7 +260,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_DOWN: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_anchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; @@ -271,7 +275,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_RIGHT_BUTTON_UP: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); if (m_scrollType == SCROLL_RMB) { @@ -283,7 +287,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; @@ -297,7 +301,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; @@ -321,7 +325,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage case GameMessage::MSG_RAW_MOUSE_POSITION: { if (m_currentPos.x != msg->getArgument( 0 )->pixel.x || m_currentPos.y != msg->getArgument( 0 )->pixel.y) - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); m_currentPos = msg->getArgument( 0 )->pixel; @@ -401,7 +405,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_WHEEL: { - m_lastMouseMoveFrame = TheGameLogic->getFrame(); + m_lastMouseMoveTimeMsec = timeGetTime(); Int spin = msg->getArgument( 1 )->integer; From 04c096a74771e93dbdaa8dff3429567e5454bf34 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 22:15:04 -0500 Subject: [PATCH 09/30] revert(input): Restore KEY_REPEAT_DELAY to original 333ms timing --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index 2a2ca0053ba..8664aa82ae7 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 250 }; + enum { KEY_REPEAT_DELAY_MSEC = 333 }; public: diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 0b5e26cbd2d..e2163ac2711 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -87,7 +87,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 250 }; + enum { KEY_REPEAT_DELAY_MSEC = 333 }; public: From 2838b28ca2e7dc4bb7813dc131bcd63a9cb152dc Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 22:22:07 -0500 Subject: [PATCH 10/30] fix(input): Correct keyboard repeat interval math to match original behavior --- Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 2 +- .../GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | 4 ++-- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 2 +- .../GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 750f76cbd3c..a8c7ab074b7 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -248,7 +248,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].sequence = m_inputFrame; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 00590a35642..df7bb4cb76d 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -282,8 +282,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { stopScrolling(); } - break; - } + break; + } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 534843c807b..71c67228096 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -248,7 +248,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].sequence = m_inputFrame; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC - KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index c20e6232601..fe83b6764bb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -281,8 +281,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage { stopScrolling(); } - break; - } + break; + } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: From f33d3a04a03d1feeef5791eedb51cdcb9d834bf4 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 22:54:47 -0500 Subject: [PATCH 11/30] refactor(input): Remove obsolete sequence field from keyboard input system --- .../Code/GameEngine/Include/GameClient/Keyboard.h | 2 -- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 13 ------------- .../Win32Device/GameClient/Win32DIKeyboard.cpp | 4 ---- .../Code/GameEngine/Include/GameClient/Keyboard.h | 2 -- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 13 ------------- .../Win32Device/GameClient/Win32DIKeyboard.cpp | 4 ---- 6 files changed, 38 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index 8664aa82ae7..c89fa00fe52 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -76,7 +76,6 @@ struct KeyboardIO UnsignedByte key; // KeyDefType, key data UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h - UnsignedInt sequence; // DirectInput sequence number; overwritten with frame number for ordering UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; @@ -134,7 +133,6 @@ class Keyboard : public SubsystemInterface Bool checkKeyRepeat( void ); ///< check for repeating keys UnsignedByte getKeyStatusData( KeyDefType key ); ///< get key status Bool getKeyStateBit( KeyDefType key, Int bit ); ///< get key state bit - UnsignedInt getKeySequenceData( KeyDefType key ); ///< get key sequence void setKeyStateData( KeyDefType key, UnsignedByte data ); ///< get key state UnsignedShort m_modifiers; diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index a8c7ab074b7..a9cdba62820 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -143,7 +143,6 @@ void Keyboard::updateKeys( void ) m_keyStatus[ m_keys[ index ].key ].state = m_keys[ index ].state; m_keyStatus[ m_keys[ index ].key ].status = m_keys[ index ].status; - m_keyStatus[ m_keys[ index ].key ].sequence = m_inputFrame; // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) @@ -243,10 +242,6 @@ Bool Keyboard::checkKeyRepeat( void ) // Set End Flag m_keys[ ++index ].key = KEY_NONE; - // Set all keys as new to prevent multiple keys repeating - for( index = 0; index< NUM_KEYS; index++ ) - m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again after the interval m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); @@ -832,14 +827,6 @@ Bool Keyboard::getKeyStateBit( KeyDefType key, Int bit ) return (m_keyStatus[ key ].state & bit) ? 1 : 0; } -//------------------------------------------------------------------------------------------------- -/** return the sequence data for the given key */ -//------------------------------------------------------------------------------------------------- -UnsignedInt Keyboard::getKeySequenceData( KeyDefType key ) -{ - return m_keyStatus[ key ].sequence; -} - //------------------------------------------------------------------------------------------------- /** set the key status data */ //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp index 6bc06e14eaf..33473f9f73a 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp @@ -251,7 +251,6 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) HRESULT hr; assert( key ); - key->sequence = 0; key->key = KEY_NONE; if( m_pKeyboardDevice ) @@ -315,9 +314,6 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) // set the key key->key = (UnsignedByte)(kbdat.dwOfs & 0xFF); - // sequence - key->sequence = kbdat.dwSequence; - // // state of key, note we are setting the key state here with an assignment // and not a bit set of the up/down state, this is the "start" diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index e2163ac2711..c2919c386c1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -76,7 +76,6 @@ struct KeyboardIO UnsignedByte key; // KeyDefType, key data UnsignedByte status; // StatusType, above UnsignedShort state; // KEY_STATE_* in KeyDefs.h - UnsignedInt sequence; // DirectInput sequence number; overwritten with frame number for ordering UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down }; @@ -134,7 +133,6 @@ class Keyboard : public SubsystemInterface Bool checkKeyRepeat( void ); ///< check for repeating keys UnsignedByte getKeyStatusData( KeyDefType key ); ///< get key status Bool getKeyStateBit( KeyDefType key, Int bit ); ///< get key state bit - UnsignedInt getKeySequenceData( KeyDefType key ); ///< get key sequence void setKeyStateData( KeyDefType key, UnsignedByte data ); ///< get key state UnsignedShort m_modifiers; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 71c67228096..ea365105524 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -143,7 +143,6 @@ void Keyboard::updateKeys( void ) m_keyStatus[ m_keys[ index ].key ].state = m_keys[ index ].state; m_keyStatus[ m_keys[ index ].key ].status = m_keys[ index ].status; - m_keyStatus[ m_keys[ index ].key ].sequence = m_inputFrame; // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) @@ -243,10 +242,6 @@ Bool Keyboard::checkKeyRepeat( void ) // Set End Flag m_keys[ ++index ].key = KEY_NONE; - // Set all keys as new to prevent multiple keys repeating - for( index = 0; index< NUM_KEYS; index++ ) - m_keyStatus[ index ].sequence = m_inputFrame; - // Set repeated key so it will repeat again after the interval m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); @@ -832,14 +827,6 @@ Bool Keyboard::getKeyStateBit( KeyDefType key, Int bit ) return (m_keyStatus[ key ].state & bit) ? 1 : 0; } -//------------------------------------------------------------------------------------------------- -/** return the sequence data for the given key */ -//------------------------------------------------------------------------------------------------- -UnsignedInt Keyboard::getKeySequenceData( KeyDefType key ) -{ - return m_keyStatus[ key ].sequence; -} - //------------------------------------------------------------------------------------------------- /** set the key status data */ //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp index 027a95f479d..02c93f28630 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp @@ -251,7 +251,6 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) HRESULT hr; assert( key ); - key->sequence = 0; key->key = KEY_NONE; if( m_pKeyboardDevice ) @@ -315,9 +314,6 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) // set the key key->key = (UnsignedByte)(kbdat.dwOfs & 0xFF); - // sequence - key->sequence = kbdat.dwSequence; - // // state of key, note we are setting the key state here with an assignment // and not a bit set of the up/down state, this is the "start" From 3c4f14a29b45bd0b3e3d77cf2421b5ce1b8953bf Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 22:59:29 -0500 Subject: [PATCH 12/30] refactor(input): Simplify timeGetTime calls --- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 12 +++--------- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 12 +++--------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index a9cdba62820..2c208587a2a 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -130,9 +130,6 @@ void Keyboard::updateKeys( void ) } while( m_keys[ index++ ].key != KEY_NONE ); - // Get current time once for all key updates - UnsignedInt now = 0; - // update keyboard status array index = 0; while( m_keys[ index ].key != KEY_NONE ) @@ -147,9 +144,7 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - if( !now ) - now = timeGetTime(); - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = now; + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); } // prevent ALT-TAB from causing a TAB event @@ -225,14 +220,13 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS - UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + if( timeGetTime() - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -243,7 +237,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keys[ ++index ].key = KEY_NONE; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = timeGetTime() - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index ea365105524..3f7b94b3597 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -130,9 +130,6 @@ void Keyboard::updateKeys( void ) } while( m_keys[ index++ ].key != KEY_NONE ); - // Get current time once for all key updates - UnsignedInt now = 0; - // update keyboard status array index = 0; while( m_keys[ index ].key != KEY_NONE ) @@ -147,9 +144,7 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - if( !now ) - now = timeGetTime(); - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = now; + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); } // prevent ALT-TAB from causing a TAB event @@ -225,14 +220,13 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS - UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + if( timeGetTime() - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -243,7 +237,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keys[ ++index ].key = KEY_NONE; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = timeGetTime() - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key From 2e3f0bd76412f756d2ecac45ffdc6379c939cc46 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 23:13:13 -0500 Subject: [PATCH 13/30] fix(input): Restore multi-key repeat prevention with time-based logic --- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 9 +++++++-- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 2c208587a2a..41dbd5f08d9 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -220,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( timeGetTime() - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -236,8 +237,12 @@ Bool Keyboard::checkKeyRepeat( void ) // Set End Flag m_keys[ ++index ].key = KEY_NONE; + // Set all keys as new to prevent multiple keys repeating + for( index = 0; index< NUM_KEYS; index++ ) + m_keyStatus[ index ].keyDownTimeMsec = now; + // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = timeGetTime() - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 3f7b94b3597..fe4aa740dff 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -220,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS + UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - if( timeGetTime() - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -236,8 +237,12 @@ Bool Keyboard::checkKeyRepeat( void ) // Set End Flag m_keys[ ++index ].key = KEY_NONE; + // Set all keys as new to prevent multiple keys repeating + for( index = 0; index< NUM_KEYS; index++ ) + m_keyStatus[ index ].keyDownTimeMsec = now; + // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = timeGetTime() - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key From e98ea02f4be7a9343ae47664d2c1ff682e00ba00 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 3 Dec 2025 23:23:45 -0500 Subject: [PATCH 14/30] perf(input): Gate timeGetTime call behind key down check in repeat logic --- Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 3 ++- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 41dbd5f08d9..2e037b36426 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -220,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS - UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { + UnsignedInt now = timeGetTime(); + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index fe4aa740dff..20fdc4c049e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -220,13 +220,14 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS - UnsignedInt now = timeGetTime(); for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { + UnsignedInt now = timeGetTime(); + if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame From 03d984dc477722c705ac99a5b4afc7c7a4044a0e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 10 Dec 2025 17:08:45 -0500 Subject: [PATCH 15/30] perf(input): Reuse timeGetTime value in middle mouse button handlers --- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 10 ++++++---- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index df7bb4cb76d..91272654e08 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -288,21 +288,23 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - m_lastMouseMoveTimeMsec = timeGetTime(); + UnsignedInt now = timeGetTime(); + m_lastMouseMoveTimeMsec = now; m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMsec = timeGetTime(); + m_middleButtonDownTimeMsec = now; break; } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - m_lastMouseMoveTimeMsec = timeGetTime(); + UnsignedInt now = timeGetTime(); + m_lastMouseMoveTimeMsec = now; const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; @@ -313,7 +315,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && timeGetTime() - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) + if (!didMove && now - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index fe83b6764bb..c102eb080e7 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -287,21 +287,23 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - m_lastMouseMoveTimeMsec = timeGetTime(); + UnsignedInt now = timeGetTime(); + m_lastMouseMoveTimeMsec = now; m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMsec = timeGetTime(); + m_middleButtonDownTimeMsec = now; break; } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - m_lastMouseMoveTimeMsec = timeGetTime(); + UnsignedInt now = timeGetTime(); + m_lastMouseMoveTimeMsec = now; const UnsignedInt CLICK_DURATION_MSEC = 167; const UnsignedInt PIXEL_OFFSET = 5; @@ -312,7 +314,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; // if middle button is "clicked", reset to "home" orientation - if (!didMove && timeGetTime() - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) + if (!didMove && now - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); From 627657ad26aeba59bd4a053679ffd63f4b3ad78a Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 10 Dec 2025 17:09:23 -0500 Subject: [PATCH 16/30] refactor(input): Move KEY_REPEAT_INTERVAL_MSEC to class enum --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 3 +-- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 2 +- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index c89fa00fe52..8cef354e472 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -86,7 +86,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 333 }; + enum { KEY_REPEAT_DELAY_MSEC = 333, KEY_REPEAT_INTERVAL_MSEC = 67 }; // ~2 frames at 30 FPS public: diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 2e037b36426..d36bfe6a731 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -219,7 +219,6 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat - const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { @@ -243,7 +242,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].keyDownTimeMsec = now; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + Keyboard::KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index c2919c386c1..588346c381d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -86,7 +86,7 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 333 }; + enum { KEY_REPEAT_DELAY_MSEC = 333, KEY_REPEAT_INTERVAL_MSEC = 67 }; // ~2 frames at 30 FPS public: diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 20fdc4c049e..15c53890942 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -219,7 +219,6 @@ Bool Keyboard::checkKeyRepeat( void ) // Scan Keyboard status array for first key down // long enough to repeat - const UnsignedInt KEY_REPEAT_INTERVAL_MSEC = 67; // ~2 frames at 30 FPS for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ ) { @@ -243,7 +242,7 @@ Bool Keyboard::checkKeyRepeat( void ) m_keyStatus[ index ].keyDownTimeMsec = now; // Set repeated key so it will repeat again after the interval - m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + KEY_REPEAT_INTERVAL_MSEC); + m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + Keyboard::KEY_REPEAT_INTERVAL_MSEC); retVal = TRUE; break; // exit for key From 22c8223bd6536226e6b83f8f968952960abbacfd Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 12 Dec 2025 13:54:08 -0500 Subject: [PATCH 17/30] refactor(input): Remove unused m_inputFrame vars and rename mouse frame fields to boolean flags --- .../GameEngine/Include/GameClient/Keyboard.h | 1 - .../GameEngine/Include/GameClient/Mouse.h | 9 ++--- .../Source/GameClient/Input/Keyboard.cpp | 7 ---- .../Source/GameClient/Input/Mouse.cpp | 37 +++++++----------- .../Win32Device/GameClient/Win32DIMouse.cpp | 8 ++-- .../Win32Device/GameClient/Win32Mouse.cpp | 31 +++++---------- .../GameEngine/Include/GameClient/Keyboard.h | 1 - .../GameEngine/Include/GameClient/Mouse.h | 9 ++--- .../Source/GameClient/Input/Keyboard.cpp | 7 ---- .../Source/GameClient/Input/Mouse.cpp | 38 +++++++------------ .../Win32Device/GameClient/Win32DIMouse.cpp | 8 ++-- .../Win32Device/GameClient/Win32Mouse.cpp | 31 +++++---------- 12 files changed, 60 insertions(+), 127 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index 8cef354e472..bc62a951ad1 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -160,7 +160,6 @@ class Keyboard : public SubsystemInterface WideChar shifted2; } m_keyNames[ KEY_COUNT ]; - UnsignedInt m_inputFrame; ///< frame input was gathered on }; diff --git a/Generals/Code/GameEngine/Include/GameClient/Mouse.h b/Generals/Code/GameEngine/Include/GameClient/Mouse.h index 92fd80497c6..ac168096858 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Mouse.h +++ b/Generals/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Int leftFrame; // last frame button state changed + Bool leftButtonStateChanged; // TRUE if button state changed in this event MouseButtonState rightState; Int rightEvent; - Int rightFrame; + Bool rightButtonStateChanged; // TRUE if button state changed in this event MouseButtonState middleState; Int middleEvent; - Int middleFrame; + Bool middleButtonStateChanged; // TRUE if button state changed in this event }; class CursorInfo @@ -393,9 +393,6 @@ class Mouse : public SubsystemInterface Int m_minY; ///< mouse is locked to this region Int m_maxY; ///< mouse is locked to this region - UnsignedInt m_inputFrame; ///< frame input was gathered on - UnsignedInt m_deadInputFrame; ///< Frame which last input occured - Bool m_inputMovesAbsolute; /**< if TRUE, when processing mouse position chanages the movement will be done treating the coords as ABSOLUTE positions and NOT diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index d36bfe6a731..d972288a823 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -701,7 +701,6 @@ Keyboard::Keyboard( void ) m_shift2Key = KEY_NONE; memset( m_keyNames, 0, sizeof( m_keyNames ) ); - m_inputFrame = 0; } @@ -721,9 +720,6 @@ void Keyboard::init( void ) // initialize the key names initKeyNames(); - // first input frame - m_inputFrame = 0; - } //------------------------------------------------------------------------------------------------- @@ -740,9 +736,6 @@ void Keyboard::reset( void ) void Keyboard::update( void ) { - // increment input frame - m_inputFrame++; - // update the key data updateKeys(); diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index 903a52b8a20..c93259bf799 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -183,9 +183,6 @@ void Mouse::updateMouseData( ) else m_eventsThisFrame = 0; - if( index != 0 ) - m_deadInputFrame = m_inputFrame; - } //------------------------------------------------------------------------------------------------- @@ -221,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftFrame ) + if( m_mouseEvents[ index ].leftButtonStateChanged ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -231,21 +228,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } } } @@ -257,7 +254,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightFrame ) + if( m_mouseEvents[ index ].rightButtonStateChanged ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -267,21 +264,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } } } @@ -293,7 +290,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleFrame ) + if( m_mouseEvents[ index ].middleButtonStateChanged ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -302,20 +299,20 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } } } @@ -328,7 +325,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.deltaPos.x = m_currMouse.pos.x - m_prevMouse.pos.x; m_currMouse.deltaPos.y = m_currMouse.pos.y - m_prevMouse.pos.y; -// DEBUG_LOG(("Mouse dx %d, dy %d, index %d, frame %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index, m_inputFrame)); +// DEBUG_LOG(("Mouse dx %d, dy %d, index %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index)); // // check if mouse is still and flag tooltip // if( ((dx*dx) + (dy*dy)) < CURSOR_MOVE_TOL_SQ ) // { @@ -474,9 +471,6 @@ Mouse::Mouse( void ) m_maxY = 0; m_eventsThisFrame = 0; - m_inputFrame = 0; - m_deadInputFrame =0; - m_inputMovesAbsolute = FALSE; m_currentCursor = ARROW; @@ -590,8 +584,6 @@ void Mouse::init( void ) m_minY = 0; m_maxY = 599; - m_inputFrame = 0; - m_deadInputFrame =0; m_inputMovesAbsolute = FALSE; m_eventsThisFrame = 0; @@ -676,9 +668,6 @@ void Mouse::reset( void ) void Mouse::update( void ) { - // increment input frame - m_inputFrame++; - // update the mouse data updateMouseData( ); diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index 56eadc80fb2..4fea54a1ddc 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftFrame = result->middleFrame = result->rightFrame = 0; + result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -283,17 +283,17 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, { case DIMOFS_BUTTON0: mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftFrame = mdat->dwSequence; + mouse->leftButtonStateChanged = TRUE; break; case DIMOFS_BUTTON1: mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightFrame = mdat->dwSequence; + mouse->rightButtonStateChanged = TRUE; break; case DIMOFS_BUTTON2: mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleFrame = mdat->dwSequence; + mouse->middleButtonStateChanged = TRUE; break; case DIMOFS_BUTTON3: diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index 5f84cca905b..023f7575718 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -85,21 +85,10 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) UINT msg = m_eventBuffer[ eventIndex ].msg; WPARAM wParam = m_eventBuffer[ eventIndex ].wParam; LPARAM lParam = m_eventBuffer[ eventIndex ].lParam; - UnsignedInt frame; - - // - // get the current input frame from the client, if we don't have - // a client (like in the GUI editor) we just use frame 1 so it - // registers with the system - // - if( TheGameClient ) - frame = TheGameClient->getFrame(); - else - frame = 1; // set these to defaults result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftFrame = result->middleFrame = result->rightFrame = 0; + result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -113,7 +102,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -125,7 +114,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -137,7 +126,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -149,7 +138,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -161,7 +150,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -173,7 +162,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -185,7 +174,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -197,7 +186,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -209,7 +198,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 588346c381d..acc5b7de688 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -160,7 +160,6 @@ class Keyboard : public SubsystemInterface WideChar shifted2; } m_keyNames[ KEY_COUNT ]; - UnsignedInt m_inputFrame; ///< frame input was gathered on }; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h index abd5c0c403d..f4d0aa68a41 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Int leftFrame; // last frame button state changed + Bool leftButtonStateChanged; // TRUE if button state changed in this event MouseButtonState rightState; Int rightEvent; - Int rightFrame; + Bool rightButtonStateChanged; // TRUE if button state changed in this event MouseButtonState middleState; Int middleEvent; - Int middleFrame; + Bool middleButtonStateChanged; // TRUE if button state changed in this event }; class CursorInfo @@ -394,9 +394,6 @@ class Mouse : public SubsystemInterface Int m_minY; ///< mouse is locked to this region Int m_maxY; ///< mouse is locked to this region - UnsignedInt m_inputFrame; ///< frame input was gathered on - UnsignedInt m_deadInputFrame; ///< Frame which last input occured - Bool m_inputMovesAbsolute; /**< if TRUE, when processing mouse position chanages the movement will be done treating the coords as ABSOLUTE positions and NOT diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 15c53890942..c9ac28293f5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -701,7 +701,6 @@ Keyboard::Keyboard( void ) m_shift2Key = KEY_NONE; memset( m_keyNames, 0, sizeof( m_keyNames ) ); - m_inputFrame = 0; } @@ -721,9 +720,6 @@ void Keyboard::init( void ) // initialize the key names initKeyNames(); - // first input frame - m_inputFrame = 0; - } //------------------------------------------------------------------------------------------------- @@ -740,9 +736,6 @@ void Keyboard::reset( void ) void Keyboard::update( void ) { - // increment input frame - m_inputFrame++; - // update the key data updateKeys(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index db0e9c745f2..b637f5cb7af 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -183,9 +183,6 @@ void Mouse::updateMouseData( ) else m_eventsThisFrame = 0; - if( index != 0 ) - m_deadInputFrame = m_inputFrame; - } //------------------------------------------------------------------------------------------------- @@ -221,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftFrame ) + if( m_mouseEvents[ index ].leftButtonStateChanged ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -231,21 +228,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftFrame = m_inputFrame; + m_currMouse.leftButtonStateChanged = TRUE; } } } @@ -257,7 +254,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightFrame ) + if( m_mouseEvents[ index ].rightButtonStateChanged ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -267,21 +264,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightFrame = m_inputFrame; + m_currMouse.rightButtonStateChanged = TRUE; } } } @@ -293,7 +290,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleFrame ) + if( m_mouseEvents[ index ].middleButtonStateChanged ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -302,20 +299,20 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleFrame = m_inputFrame; + m_currMouse.middleButtonStateChanged = TRUE; } } } @@ -328,7 +325,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.deltaPos.x = m_currMouse.pos.x - m_prevMouse.pos.x; m_currMouse.deltaPos.y = m_currMouse.pos.y - m_prevMouse.pos.y; -// DEBUG_LOG(("Mouse dx %d, dy %d, index %d, frame %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index, m_inputFrame)); +// DEBUG_LOG(("Mouse dx %d, dy %d, index %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index)); // // check if mouse is still and flag tooltip // if( ((dx*dx) + (dy*dy)) < CURSOR_MOVE_TOL_SQ ) // { @@ -474,9 +471,6 @@ Mouse::Mouse( void ) m_maxY = 0; m_eventsThisFrame = 0; - m_inputFrame = 0; - m_deadInputFrame =0; - m_inputMovesAbsolute = FALSE; m_currentCursor = ARROW; @@ -590,9 +584,6 @@ void Mouse::init( void ) m_minY = 0; m_maxY = 599; - m_inputFrame = 0; - m_deadInputFrame =0; - m_inputMovesAbsolute = FALSE; m_eventsThisFrame = 0; @@ -676,9 +667,6 @@ void Mouse::reset( void ) void Mouse::update( void ) { - // increment input frame - m_inputFrame++; - // update the mouse data updateMouseData( ); diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index e5b195fe6c1..0fd47dabd1b 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftFrame = result->middleFrame = result->rightFrame = 0; + result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -283,17 +283,17 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, { case DIMOFS_BUTTON0: mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftFrame = mdat->dwSequence; + mouse->leftButtonStateChanged = TRUE; break; case DIMOFS_BUTTON1: mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightFrame = mdat->dwSequence; + mouse->rightButtonStateChanged = TRUE; break; case DIMOFS_BUTTON2: mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleFrame = mdat->dwSequence; + mouse->middleButtonStateChanged = TRUE; break; case DIMOFS_BUTTON3: diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index 9b89deba00d..adacd425351 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -85,21 +85,10 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) UINT msg = m_eventBuffer[ eventIndex ].msg; WPARAM wParam = m_eventBuffer[ eventIndex ].wParam; LPARAM lParam = m_eventBuffer[ eventIndex ].lParam; - UnsignedInt frame; - - // - // get the current input frame from the client, if we don't have - // a client (like in the GUI editor) we just use frame 1 so it - // registers with the system - // - if( TheGameClient ) - frame = TheGameClient->getFrame(); - else - frame = 1; // set these to defaults result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftFrame = result->middleFrame = result->rightFrame = 0; + result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -113,7 +102,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -125,7 +114,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -137,7 +126,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftFrame = frame; + result->leftButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -149,7 +138,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -161,7 +150,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -173,7 +162,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleFrame = frame; + result->middleButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -185,7 +174,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -197,7 +186,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -209,7 +198,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightFrame = frame; + result->rightButtonStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; From f1034fa3ca1ffc3817c517295e051c6ec0c2b6ea Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 12 Dec 2025 14:21:54 -0500 Subject: [PATCH 18/30] nit: Clarify comment for mouse button state changed fields --- Generals/Code/GameEngine/Include/GameClient/Mouse.h | 6 +++--- GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Mouse.h b/Generals/Code/GameEngine/Include/GameClient/Mouse.h index ac168096858..b6b8e97fba3 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Mouse.h +++ b/Generals/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Bool leftButtonStateChanged; // TRUE if button state changed in this event + Bool leftButtonStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightButtonStateChanged; // TRUE if button state changed in this event + Bool rightButtonStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleButtonStateChanged; // TRUE if button state changed in this event + Bool middleButtonStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h index f4d0aa68a41..abaab8abe6c 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Bool leftButtonStateChanged; // TRUE if button state changed in this event + Bool leftButtonStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightButtonStateChanged; // TRUE if button state changed in this event + Bool rightButtonStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleButtonStateChanged; // TRUE if button state changed in this event + Bool middleButtonStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo From 870dc2834db44967fa93621b2a054c4ebea1d30f Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 13 Dec 2025 07:19:33 -0500 Subject: [PATCH 19/30] perf(input): Use DirectInput timestamp for key down time and update comment --- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 4 ++-- .../Source/Win32Device/GameClient/Win32DIKeyboard.cpp | 10 +++++++++- .../GameEngine/Source/GameClient/Input/Keyboard.cpp | 4 ++-- .../Source/Win32Device/GameClient/Win32DIKeyboard.cpp | 10 +++++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index d972288a823..9aad0693ac6 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -144,7 +144,7 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = m_keys[ index ].keyDownTimeMsec; } // prevent ALT-TAB from causing a TAB event @@ -200,7 +200,7 @@ void Keyboard::updateKeys( void ) } //------------------------------------------------------------------------------------------------- -/** check key repeat sequences, TRUE is returned if repeat is occurring */ +/** check key repeat timing, TRUE is returned if repeat is occurring */ //------------------------------------------------------------------------------------------------- Bool Keyboard::checkKeyRepeat( void ) { diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp index 33473f9f73a..f0b7d39b155 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp @@ -319,7 +319,15 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) // and not a bit set of the up/down state, this is the "start" // of building this "key" // - key->state = (( kbdat.dwData & 0x0080 ) ? KEY_STATE_DOWN : KEY_STATE_UP); + if( kbdat.dwData & 0x0080 ) + { + key->state = KEY_STATE_DOWN; + key->keyDownTimeMsec = kbdat.dwTimeStamp; + } + else + { + key->state = KEY_STATE_UP; + } // set status as unused (unprocessed) key->status = KeyboardIO::STATUS_UNUSED; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index c9ac28293f5..b98b5dceb14 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -144,7 +144,7 @@ void Keyboard::updateKeys( void ) // Update key down time for new key presses if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) ) { - m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = timeGetTime(); + m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = m_keys[ index ].keyDownTimeMsec; } // prevent ALT-TAB from causing a TAB event @@ -200,7 +200,7 @@ void Keyboard::updateKeys( void ) } //------------------------------------------------------------------------------------------------- -/** check key repeat sequences, TRUE is returned if repeat is occurring */ +/** check key repeat timing, TRUE is returned if repeat is occurring */ //------------------------------------------------------------------------------------------------- Bool Keyboard::checkKeyRepeat( void ) { diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp index 02c93f28630..0591902e29f 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIKeyboard.cpp @@ -319,7 +319,15 @@ void DirectInputKeyboard::getKey( KeyboardIO *key ) // and not a bit set of the up/down state, this is the "start" // of building this "key" // - key->state = (( kbdat.dwData & 0x0080 ) ? KEY_STATE_DOWN : KEY_STATE_UP); + if( kbdat.dwData & 0x0080 ) + { + key->state = KEY_STATE_DOWN; + key->keyDownTimeMsec = kbdat.dwTimeStamp; + } + else + { + key->state = KEY_STATE_UP; + } // set status as unused (unprocessed) key->status = KeyboardIO::STATUS_UNUSED; From cf2a6d6f010ad8d0370c57569d1af57da43ce35b Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 13 Dec 2025 18:23:41 -0500 Subject: [PATCH 20/30] fix: Remove double empty line to match GeneralsMD formatting --- Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index c93259bf799..cf12f6e96db 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -584,7 +584,6 @@ void Mouse::init( void ) m_minY = 0; m_maxY = 599; - m_inputMovesAbsolute = FALSE; m_eventsThisFrame = 0; From 2453557d553e98fd0bd0cbf552392db8d2fd5b32 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:32:34 -0500 Subject: [PATCH 21/30] refactor(input): Use MSEC_PER_SECOND constant in LookAtXlat --- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index c102eb080e7..2ccb0ea34d5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -171,14 +171,13 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - const UnsignedInt ONE_SECOND_MSEC = 1000; UnsignedInt now = timeGetTime(); // Handle time wraparound if (now < m_lastMouseMoveTimeMsec) m_lastMouseMoveTimeMsec = now; - if (now - m_lastMouseMoveTimeMsec > ONE_SECOND_MSEC) + if (now - m_lastMouseMoveTimeMsec > MSEC_PER_SECOND) return false; return true; @@ -287,22 +286,22 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); m_lastMouseMoveTimeMsec = now; + m_middleButtonDownTimeMsec = now; m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMsec = now; break; } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); m_lastMouseMoveTimeMsec = now; const UnsignedInt CLICK_DURATION_MSEC = 167; From f52de9f46669f100022cc6c2752d979d345a5e95 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:32:37 -0500 Subject: [PATCH 22/30] style(input): Format keyboard repeat enum across multiple lines --- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index acc5b7de688..14960bca3ee 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -86,7 +86,11 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 333, KEY_REPEAT_INTERVAL_MSEC = 67 }; // ~2 frames at 30 FPS + enum + { + KEY_REPEAT_DELAY_MSEC = 333, + KEY_REPEAT_INTERVAL_MSEC = 67 + }; // ~2 frames at 30 FPS public: From 7c64dfc1827322c6d28cede85c59bf133152a521 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:32:39 -0500 Subject: [PATCH 23/30] refactor(input): Rename mouse button state changed variables --- .../GameEngine/Include/GameClient/Mouse.h | 6 ++--- .../Source/GameClient/Input/Mouse.cpp | 24 +++++++++---------- .../Win32Device/GameClient/Win32DIMouse.cpp | 8 +++---- .../Win32Device/GameClient/Win32Mouse.cpp | 20 ++++++++-------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h index abaab8abe6c..ef9e6f07bfd 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Bool leftButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool leftStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool rightStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool middleStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index b637f5cb7af..b2bd57ac40e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -218,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftButtonStateChanged ) + if( m_mouseEvents[ index ].leftStateChanged ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -228,21 +228,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } } } @@ -254,7 +254,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightButtonStateChanged ) + if( m_mouseEvents[ index ].rightStateChanged ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -264,21 +264,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } } } @@ -290,7 +290,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleButtonStateChanged ) + if( m_mouseEvents[ index ].middleStateChanged ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -299,20 +299,20 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } } } diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index 0fd47dabd1b..e410bb0555e 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; + result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -283,17 +283,17 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, { case DIMOFS_BUTTON0: mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftButtonStateChanged = TRUE; + mouse->leftStateChanged = TRUE; break; case DIMOFS_BUTTON1: mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightButtonStateChanged = TRUE; + mouse->rightStateChanged = TRUE; break; case DIMOFS_BUTTON2: mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleButtonStateChanged = TRUE; + mouse->middleStateChanged = TRUE; break; case DIMOFS_BUTTON3: diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index adacd425351..69836e157ff 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -88,7 +88,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) // set these to defaults result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; + result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -102,7 +102,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -114,7 +114,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -126,7 +126,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -138,7 +138,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -150,7 +150,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -162,7 +162,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -174,7 +174,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -186,7 +186,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -198,7 +198,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; From b6c9028ae5da08854add514f71ce74c27b86b812 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:33:03 -0500 Subject: [PATCH 24/30] refactor(input): Use MSEC_PER_SECOND constant in LookAtXlat --- .../Source/GameClient/MessageStream/LookAtXlat.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 91272654e08..0eb47bca583 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -171,14 +171,13 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - const UnsignedInt ONE_SECOND_MSEC = 1000; UnsignedInt now = timeGetTime(); // Handle time wraparound if (now < m_lastMouseMoveTimeMsec) m_lastMouseMoveTimeMsec = now; - if (now - m_lastMouseMoveTimeMsec > ONE_SECOND_MSEC) + if (now - m_lastMouseMoveTimeMsec > MSEC_PER_SECOND) return false; return true; @@ -288,22 +287,22 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_DOWN: { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); m_lastMouseMoveTimeMsec = now; + m_middleButtonDownTimeMsec = now; m_isRotating = true; m_anchor = msg->getArgument( 0 )->pixel; m_anchorAngle = TheTacticalView->getAngle(); m_originalAnchor = msg->getArgument( 0 )->pixel; m_currentPos = msg->getArgument( 0 )->pixel; - m_middleButtonDownTimeMsec = now; break; } //----------------------------------------------------------------------------- case GameMessage::MSG_RAW_MOUSE_MIDDLE_BUTTON_UP: { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); m_lastMouseMoveTimeMsec = now; const UnsignedInt CLICK_DURATION_MSEC = 167; From 8f84f20b3089c728e930e15c814f7f7fdf8db970 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:33:05 -0500 Subject: [PATCH 25/30] style(input): Format keyboard repeat enum across multiple lines --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index bc62a951ad1..ee524849911 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -86,7 +86,11 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY_MSEC = 333, KEY_REPEAT_INTERVAL_MSEC = 67 }; // ~2 frames at 30 FPS + enum + { + KEY_REPEAT_DELAY_MSEC = 333, + KEY_REPEAT_INTERVAL_MSEC = 67 + }; // ~2 frames at 30 FPS public: From ea94ee7a592718003a9f3e342e79754749f81d30 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 19 Dec 2025 10:33:07 -0500 Subject: [PATCH 26/30] refactor(input): Rename mouse button state changed variables --- .../GameEngine/Include/GameClient/Mouse.h | 6 ++--- .../Source/GameClient/Input/Mouse.cpp | 24 +++++++++---------- .../Win32Device/GameClient/Win32DIMouse.cpp | 8 +++---- .../Win32Device/GameClient/Win32Mouse.cpp | 20 ++++++++-------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Mouse.h b/Generals/Code/GameEngine/Include/GameClient/Mouse.h index b6b8e97fba3..838a99368b5 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Mouse.h +++ b/Generals/Code/GameEngine/Include/GameClient/Mouse.h @@ -107,15 +107,15 @@ struct MouseIO MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) Int leftEvent; // Most important event this frame - Bool leftButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool leftStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool rightStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleButtonStateChanged; // TRUE if button state changed for a given mouse event + Bool middleStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index cf12f6e96db..3784c593bc5 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -218,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftButtonStateChanged ) + if( m_mouseEvents[ index ].leftStateChanged ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -228,21 +228,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftButtonStateChanged = TRUE; + m_currMouse.leftStateChanged = TRUE; } } } @@ -254,7 +254,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightButtonStateChanged ) + if( m_mouseEvents[ index ].rightStateChanged ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -264,21 +264,21 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightButtonStateChanged = TRUE; + m_currMouse.rightStateChanged = TRUE; } } } @@ -290,7 +290,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleButtonStateChanged ) + if( m_mouseEvents[ index ].middleStateChanged ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -299,20 +299,20 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleButtonStateChanged = TRUE; + m_currMouse.middleStateChanged = TRUE; } } } diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index 4fea54a1ddc..10c0b0a8a6d 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; + result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -283,17 +283,17 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, { case DIMOFS_BUTTON0: mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftButtonStateChanged = TRUE; + mouse->leftStateChanged = TRUE; break; case DIMOFS_BUTTON1: mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightButtonStateChanged = TRUE; + mouse->rightStateChanged = TRUE; break; case DIMOFS_BUTTON2: mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleButtonStateChanged = TRUE; + mouse->middleStateChanged = TRUE; break; case DIMOFS_BUTTON3: diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index 023f7575718..45edcd06068 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -88,7 +88,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) // set these to defaults result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftButtonStateChanged = result->middleButtonStateChanged = result->rightButtonStateChanged = FALSE; + result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -102,7 +102,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -114,7 +114,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -126,7 +126,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftButtonStateChanged = TRUE; + result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -138,7 +138,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -150,7 +150,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -162,7 +162,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleButtonStateChanged = TRUE; + result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -174,7 +174,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -186,7 +186,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -198,7 +198,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightButtonStateChanged = TRUE; + result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; From eca1f267e158fe5ad241b35516ee818f07ebaa35 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 20 Dec 2025 12:29:30 -0500 Subject: [PATCH 27/30] fix(input): Move timing constant comments to correct lines --- Generals/Code/GameEngine/Include/GameClient/Keyboard.h | 6 +++--- GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h index ee524849911..8e54ae6ac1c 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/Generals/Code/GameEngine/Include/GameClient/Keyboard.h @@ -88,9 +88,9 @@ class Keyboard : public SubsystemInterface enum { - KEY_REPEAT_DELAY_MSEC = 333, - KEY_REPEAT_INTERVAL_MSEC = 67 - }; // ~2 frames at 30 FPS + KEY_REPEAT_DELAY_MSEC = 333, // 10 frames at 30 FPS + KEY_REPEAT_INTERVAL_MSEC = 67 // ~2 frames at 30 FPS + }; public: diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 14960bca3ee..79a11a6d82d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -88,9 +88,9 @@ class Keyboard : public SubsystemInterface enum { - KEY_REPEAT_DELAY_MSEC = 333, - KEY_REPEAT_INTERVAL_MSEC = 67 - }; // ~2 frames at 30 FPS + KEY_REPEAT_DELAY_MSEC = 333, // 10 frames at 30 FPS + KEY_REPEAT_INTERVAL_MSEC = 67 // ~2 frames at 30 FPS + }; public: From 2d14d5b8d7afff8e27d485e3a13c1c6502b3a7ab Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 20 Dec 2025 12:29:30 -0500 Subject: [PATCH 28/30] fix(input): Remove side effects from hasMouseMovedRecently --- .../GameClient/MessageStream/LookAtXlat.cpp | 17 ++++++++--------- .../GameClient/MessageStream/LookAtXlat.cpp | 17 ++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 0eb47bca583..761992f7438 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -171,16 +171,12 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); + const UnsignedInt lastMove = m_lastMouseMoveTimeMsec; - // Handle time wraparound - if (now < m_lastMouseMoveTimeMsec) - m_lastMouseMoveTimeMsec = now; + const UnsignedInt elapsedMsec = now - lastMove; - if (now - m_lastMouseMoveTimeMsec > MSEC_PER_SECOND) - return false; - - return true; + return elapsedMsec <= MSEC_PER_SECOND; } void LookAtTranslator::setCurrentPos( const ICoord2D& pos ) @@ -313,8 +309,11 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage if (dx<0) dx = -dx; Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; + + const UnsignedInt elapsedMsec = now - m_middleButtonDownTimeMsec; + // if middle button is "clicked", reset to "home" orientation - if (!didMove && now - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) + if (!didMove && elapsedMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp index 2ccb0ea34d5..6168f28233a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/LookAtXlat.cpp @@ -171,16 +171,12 @@ const ICoord2D* LookAtTranslator::getRMBScrollAnchor(void) Bool LookAtTranslator::hasMouseMovedRecently( void ) { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); + const UnsignedInt lastMove = m_lastMouseMoveTimeMsec; - // Handle time wraparound - if (now < m_lastMouseMoveTimeMsec) - m_lastMouseMoveTimeMsec = now; + const UnsignedInt elapsedMsec = now - lastMove; - if (now - m_lastMouseMoveTimeMsec > MSEC_PER_SECOND) - return false; - - return true; + return elapsedMsec <= MSEC_PER_SECOND; } void LookAtTranslator::setCurrentPos( const ICoord2D& pos ) @@ -312,8 +308,11 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage if (dx<0) dx = -dx; Int dy = m_currentPos.y-m_originalAnchor.y; Bool didMove = dx>PIXEL_OFFSET || dy>PIXEL_OFFSET; + + const UnsignedInt elapsedMsec = now - m_middleButtonDownTimeMsec; + // if middle button is "clicked", reset to "home" orientation - if (!didMove && now - m_middleButtonDownTimeMsec < CLICK_DURATION_MSEC) + if (!didMove && elapsedMsec < CLICK_DURATION_MSEC) { TheTacticalView->setAngleAndPitchToDefault(); TheTacticalView->setZoomToDefault(); From 7a27d2562122819e620285af18a932a24a12b047 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 20 Dec 2025 12:29:32 -0500 Subject: [PATCH 29/30] fix(input): Use unsigned subtraction for keyboard repeat timing --- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 8 ++++++-- .../Code/GameEngine/Source/GameClient/Input/Keyboard.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index 9aad0693ac6..3e69d321a36 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -225,9 +225,13 @@ Bool Keyboard::checkKeyRepeat( void ) if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); + const UnsignedInt keyDownTime = m_keyStatus[ key ].keyDownTimeMsec; - if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + // Unsigned subtraction handles wraparound correctly + const UnsignedInt elapsedMsec = now - keyDownTime; + + if( elapsedMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index b98b5dceb14..9ef9c3b1423 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -225,9 +225,11 @@ Bool Keyboard::checkKeyRepeat( void ) if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - UnsignedInt now = timeGetTime(); + const UnsignedInt now = timeGetTime(); + const UnsignedInt keyDownTime = m_keyStatus[ key ].keyDownTimeMsec; + const UnsignedInt elapsedMsec = now - keyDownTime; - if( now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) + if( elapsedMsec > Keyboard::KEY_REPEAT_DELAY_MSEC ) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; From c0465ba514a0689814fd2174548aaa6977de4340 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 20 Dec 2025 12:29:34 -0500 Subject: [PATCH 30/30] refactor(input): Replace mouse button state change flags with MBS_None enum --- .../Code/GameEngine/Include/GameClient/Mouse.h | 6 ++---- .../GameEngine/Source/GameClient/Input/Mouse.cpp | 15 +++------------ .../Win32Device/GameClient/Win32DIMouse.cpp | 11 ++++------- .../Source/Win32Device/GameClient/Win32Mouse.cpp | 12 +----------- .../Code/GameEngine/Include/GameClient/Mouse.h | 6 ++---- .../GameEngine/Source/GameClient/Input/Mouse.cpp | 15 +++------------ .../Win32Device/GameClient/Win32DIMouse.cpp | 11 ++++------- .../Source/Win32Device/GameClient/Win32Mouse.cpp | 12 +----------- 8 files changed, 20 insertions(+), 68 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/Mouse.h b/Generals/Code/GameEngine/Include/GameClient/Mouse.h index 838a99368b5..07583b79f78 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Mouse.h +++ b/Generals/Code/GameEngine/Include/GameClient/Mouse.h @@ -62,6 +62,7 @@ enum GameMode CPP_11(: Int); enum MouseButtonState CPP_11(: Int) { + MBS_None = -1, MBS_Up = 0, MBS_Down, MBS_DoubleClick, @@ -105,17 +106,14 @@ struct MouseIO user while - is down/toward user */ ICoord2D deltaPos; ///< overall change in mouse pointer this frame - MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) + MouseButtonState leftState; // button state: None (no event), Up, Down, DoubleClick Int leftEvent; // Most important event this frame - Bool leftStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index 3784c593bc5..8f02f88d27a 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -218,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftStateChanged ) + if( m_mouseEvents[ index ].leftState != MBS_None ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -228,21 +228,18 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftStateChanged = TRUE; } } } @@ -254,7 +251,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightStateChanged ) + if( m_mouseEvents[ index ].rightState != MBS_None ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -264,21 +261,18 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightStateChanged = TRUE; } } } @@ -290,7 +284,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleStateChanged ) + if( m_mouseEvents[ index ].middleState != MBS_None ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -299,20 +293,17 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleStateChanged = TRUE; } } } diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index 10c0b0a8a6d..0df595f04ca 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; + result->leftState = result->middleState = result->rightState = MBS_None; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -282,18 +282,15 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, switch( mdat->dwOfs ) { case DIMOFS_BUTTON0: - mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftStateChanged = TRUE; + mouse->leftState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON1: - mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightStateChanged = TRUE; + mouse->rightState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON2: - mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleStateChanged = TRUE; + mouse->middleState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON3: diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index 45edcd06068..533c0d908a9 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -87,8 +87,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) LPARAM lParam = m_eventBuffer[ eventIndex ].lParam; // set these to defaults - result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; + result->leftState = result->middleState = result->rightState = MBS_None; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -102,7 +101,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -114,7 +112,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -126,7 +123,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -138,7 +134,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -150,7 +145,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -162,7 +156,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -174,7 +167,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -186,7 +178,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -198,7 +189,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h index ef9e6f07bfd..6170da909f1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Mouse.h @@ -62,6 +62,7 @@ enum GameMode CPP_11(: Int); enum MouseButtonState CPP_11(: Int) { + MBS_None = -1, MBS_Up = 0, MBS_Down, MBS_DoubleClick, @@ -105,17 +106,14 @@ struct MouseIO user while - is down/toward user */ ICoord2D deltaPos; ///< overall change in mouse pointer this frame - MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down) + MouseButtonState leftState; // button state: None (no event), Up, Down, DoubleClick Int leftEvent; // Most important event this frame - Bool leftStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState rightState; Int rightEvent; - Bool rightStateChanged; // TRUE if button state changed for a given mouse event MouseButtonState middleState; Int middleEvent; - Bool middleStateChanged; // TRUE if button state changed for a given mouse event }; class CursorInfo diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index b2bd57ac40e..2310d9ccc6c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -218,7 +218,7 @@ void Mouse::processMouseEvent( Int index ) m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos; // Check Left Mouse State - if( m_mouseEvents[ index ].leftStateChanged ) + if( m_mouseEvents[ index ].leftState != MBS_None ) { if( m_currMouse.leftState != m_mouseEvents[ index ].leftState ) { @@ -228,21 +228,18 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.leftEvent = GWM_LEFT_DOWN; m_currMouse.leftState = MBS_Down; - m_currMouse.leftStateChanged = TRUE; } else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK; m_currMouse.leftState = MBS_DoubleClick; - m_currMouse.leftStateChanged = TRUE; } else { // Mouse Up m_currMouse.leftEvent = GWM_LEFT_UP; m_currMouse.leftState = MBS_Up; - m_currMouse.leftStateChanged = TRUE; } } } @@ -254,7 +251,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Right Mouse State - if( m_mouseEvents[ index ].rightStateChanged ) + if( m_mouseEvents[ index ].rightState != MBS_None ) { if( m_currMouse.rightState != m_mouseEvents[ index ].rightState ) { @@ -264,21 +261,18 @@ void Mouse::processMouseEvent( Int index ) // Mouse Down m_currMouse.rightEvent = GWM_RIGHT_DOWN; m_currMouse.rightState = MBS_Down; - m_currMouse.rightStateChanged = TRUE; } else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick ) { // Mouse Double Click m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK; m_currMouse.rightState = MBS_DoubleClick; - m_currMouse.rightStateChanged = TRUE; } else { // Mouse Up m_currMouse.rightEvent = GWM_RIGHT_UP; m_currMouse.rightState = MBS_Up; - m_currMouse.rightStateChanged = TRUE; } } } @@ -290,7 +284,7 @@ void Mouse::processMouseEvent( Int index ) } // Check Middle Mouse State - if( m_mouseEvents[ index ].middleStateChanged ) + if( m_mouseEvents[ index ].middleState != MBS_None ) { if( m_currMouse.middleState != m_mouseEvents[index].middleState ) { @@ -299,20 +293,17 @@ void Mouse::processMouseEvent( Int index ) { m_currMouse.middleEvent = GWM_MIDDLE_DOWN; m_currMouse.middleState = MBS_Down; - m_currMouse.middleStateChanged = TRUE; } else if( m_mouseEvents[index].middleState == MBS_DoubleClick ) { m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK; m_currMouse.middleState = MBS_DoubleClick; - m_currMouse.middleStateChanged = TRUE; } else { // Mouse Up m_currMouse.middleEvent = GWM_MIDDLE_UP; m_currMouse.middleState = MBS_Up; - m_currMouse.middleStateChanged = TRUE; } } } diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp index e410bb0555e..c8b59e10e62 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32DIMouse.cpp @@ -202,7 +202,7 @@ UnsignedByte DirectInputMouse::getMouseEvent( MouseIO *result, Bool flush ) /* set these to defaults */ result->leftState = result->middleState = result->rightState = FALSE; - result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; + result->leftState = result->middleState = result->rightState = MBS_None; result->pos.x = result->pos.y = result->wheelPos = 0; if( m_pMouseDevice ) @@ -282,18 +282,15 @@ void DirectInputMouse::mapDirectInputMouse( MouseIO *mouse, switch( mdat->dwOfs ) { case DIMOFS_BUTTON0: - mouse->leftState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->leftStateChanged = TRUE; + mouse->leftState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON1: - mouse->rightState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->rightStateChanged = TRUE; + mouse->rightState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON2: - mouse->middleState = (( mdat->dwData & 0x0080 ) ? TRUE : FALSE); - mouse->middleStateChanged = TRUE; + mouse->middleState = (( mdat->dwData & 0x0080 ) ? MBS_Down : MBS_Up); break; case DIMOFS_BUTTON3: diff --git a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp index 69836e157ff..085bcd461d3 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/Win32Device/GameClient/Win32Mouse.cpp @@ -87,8 +87,7 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) LPARAM lParam = m_eventBuffer[ eventIndex ].lParam; // set these to defaults - result->leftState = result->middleState = result->rightState = MBS_Up; - result->leftStateChanged = result->middleStateChanged = result->rightStateChanged = FALSE; + result->leftState = result->middleState = result->rightState = MBS_None; result->pos.x = result->pos.y = result->wheelPos = 0; // Time is the same for all events @@ -102,7 +101,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Down; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -114,7 +112,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_Up; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -126,7 +123,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->leftState = MBS_DoubleClick; - result->leftStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -138,7 +134,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Down; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -150,7 +145,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_Up; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -162,7 +156,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->middleState = MBS_DoubleClick; - result->middleStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -174,7 +167,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Down; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -186,7 +178,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_Up; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break; @@ -198,7 +189,6 @@ void Win32Mouse::translateEvent( UnsignedInt eventIndex, MouseIO *result ) { result->rightState = MBS_DoubleClick; - result->rightStateChanged = TRUE; result->pos.x = LOWORD( lParam ); result->pos.y = HIWORD( lParam ); break;