diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h index 770a7338fd..386f173194 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h @@ -84,8 +84,6 @@ struct KeyboardIO class Keyboard : public SubsystemInterface { - enum { KEY_REPEAT_DELAY = 10 }; - public: Keyboard( void ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp index 0c49c2a141..edbd19aadb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GameClient.cpp @@ -289,8 +289,8 @@ void GameClient::init( void ) // since we only allocate one of each, don't bother pooling 'em m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") WindowTranslator, 10 ); - m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") MetaEventTranslator, 20 ); - m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") HotKeyTranslator, 25 ); + m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") HotKeyTranslator, 20 ); + m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") MetaEventTranslator, 25 ); m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") PlaceEventTranslator, 30 ); m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") GUICommandTranslator, 40 ); m_translators[ m_numTranslators++ ] = TheMessageStream->attachTranslator( MSGNEW("GameClientSubsystem") SelectionTranslator, 50 ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp index a2e67445d1..61586efa1e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp @@ -32,6 +32,7 @@ #include "Common/Language.h" #include "Common/GameEngine.h" #include "Common/MessageStream.h" +#include "Common/FramePacer.h" #include "GameClient/Keyboard.h" #include "GameClient/KeyDefs.h" @@ -218,8 +219,10 @@ Bool Keyboard::checkKeyRepeat( void ) if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) ) { - - if( (m_inputFrame - m_keyStatus[ key ].sequence) > Keyboard::KEY_REPEAT_DELAY ) + // Check if key has been pressed down for longer than 125 ms + constexpr const Real initialDelayInSec = 0.125125f; + UnsignedInt initialDelayInFrames = static_cast(TheFramePacer->getUpdateFps() * initialDelayInSec); + if( (m_inputFrame - m_keyStatus[ key ].sequence) > initialDelayInFrames) { // Add key to this frame m_keys[ index ].key = (UnsignedByte)key; @@ -233,8 +236,10 @@ 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 that the next delay is much shorter than the first + constexpr const Real nextDelayMultiplier = 1.0f / 3.0f; + UnsignedInt nextDelayInFrames = clamp(initialDelayInFrames * nextDelayMultiplier, 1, 1000); + m_keyStatus[ key ].sequence = m_inputFrame - (initialDelayInFrames - nextDelayInFrames); retVal = TRUE; break; // exit for key diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp index e71399c7e8..7a2b220b56 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/HotKey.cpp @@ -69,44 +69,33 @@ //----------------------------------------------------------------------------- GameMessageDisposition HotKeyTranslator::translateGameMessage(const GameMessage *msg) { - GameMessageDisposition disp = KEEP_MESSAGE; - GameMessage::Type t = msg->getType(); - - if ( t == GameMessage::MSG_RAW_KEY_UP) + switch (msg->getType()) { + case GameMessage::MSG_RAW_KEY_DOWN: + if ((msg->getArgument(1)->integer & KEY_STATE_AUTOREPEAT) == 0) + return KEEP_MESSAGE; - //char key = msg->getArgument(0)->integer; - Int keyState = msg->getArgument(1)->integer; - - // for our purposes here, we don't care to distinguish between right and left keys, - // so just fudge a little to simplify things. - Int newModState = 0; + FALLTHROUGH; + case GameMessage::MSG_RAW_KEY_UP: + if (msg->getArgument(1)->integer & (KEY_STATE_CONTROL | KEY_STATE_SHIFT | KEY_STATE_ALT)) + return KEEP_MESSAGE; - if( keyState & KEY_STATE_CONTROL ) + if (TheHotKeyManager) { - newModState |= CTRL; + WideChar key = TheKeyboard->getPrintableKey(msg->getArgument(0)->integer, 0); + UnicodeString uKey; + uKey.concat(key); + AsciiString aKey; + aKey.translate(uKey); + + if (TheHotKeyManager->executeHotKey(aKey)) + return DESTROY_MESSAGE; } - if( keyState & KEY_STATE_SHIFT ) - { - newModState |= SHIFT; - } - - if( keyState & KEY_STATE_ALT ) - { - newModState |= ALT; - } - if(newModState != 0) - return disp; - WideChar key = TheKeyboard->getPrintableKey(msg->getArgument(0)->integer, 0); - UnicodeString uKey; - uKey.concat(key); - AsciiString aKey; - aKey.translate(uKey); - if(TheHotKeyManager && TheHotKeyManager->executeHotKey(aKey)) - disp = DESTROY_MESSAGE; + return KEEP_MESSAGE; + default: + return KEEP_MESSAGE; } - return disp; } //-----------------------------------------------------------------------------