Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ struct KeyboardIO
class Keyboard : public SubsystemInterface
{

enum { KEY_REPEAT_DELAY = 10 };

public:

Keyboard( void );
Expand Down
13 changes: 9 additions & 4 deletions GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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<UnsignedInt>(TheFramePacer->getUpdateFps() * initialDelayInSec);
if( (m_inputFrame - m_keyStatus[ key ].sequence) > initialDelayInFrames)
{
// Add key to this frame
m_keys[ index ].key = (UnsignedByte)key;
Expand All @@ -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<UnsignedInt>(initialDelayInFrames * nextDelayMultiplier, 1, 1000);
m_keyStatus[ key ].sequence = m_inputFrame - (initialDelayInFrames - nextDelayInFrames);

retVal = TRUE;
break; // exit for key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

//-----------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,22 @@ GameMessageDisposition MetaEventTranslator::translateGameMessage(const GameMessa

if( keyState & KEY_STATE_AUTOREPEAT )
{
if (!newModState)
{
if (const Drawable *selectedDrawable = TheInGameUI->getFirstSelectedDrawable())
{
if (const Object *tempObject = selectedDrawable->getObject())
{
if (tempObject->isKindOf(KINDOF_STRUCTURE))
{
// keep message for hotkey
disp = KEEP_MESSAGE;
break;
}
}
}
}

// if it's an autorepeat of a "known" key, don't generate the meta-event,
// but DO eat the keystroke so no one else can mess with it
//DEBUG_LOG(("Frame %d: MetaEventTranslator::translateGameMessage() auto-repeat: %s", TheGameLogic->getFrame(), findGameMessageNameByType(map->m_meta)));
Expand Down
Loading