Skip to content

Commit 3273071

Browse files
committed
Modified Keyboard::checkKeyRepeat.
1 parent cf56aef commit 3273071

File tree

2 files changed

+38
-34
lines changed

2 files changed

+38
-34
lines changed

GeneralsMD/Code/GameEngine/Include/GameClient/Keyboard.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct KeyboardIO
7777
UnsignedByte status; // StatusType, above
7878
UnsignedShort state; // KEY_STATE_* in KeyDefs.h
7979
UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down
80+
UnsignedInt keyRepeatTimeMsecOffset; // shorten key repeat delay by offset
8081

8182
};
8283

@@ -88,8 +89,12 @@ class Keyboard : public SubsystemInterface
8889

8990
enum
9091
{
91-
KEY_REPEAT_DELAY_MSEC = 333, // 10 frames at 30 FPS
92-
KEY_REPEAT_INTERVAL_MSEC = 67 // ~2 frames at 30 FPS
92+
// TheSuperHackers @info Holding a button down requires 200 msec to register as a repeated key for the first time.
93+
// After that the delay gets shorter and shorter, between 140 (200 - 60) and 15 (200 - 185) msec, with a decrease step of 15 msec.
94+
KEY_REPEAT_DELAY_MSEC = 200,
95+
KEY_REPEAT_OFFSET_DELAY_MIN_MSEC = 60,
96+
KEY_REPEAT_OFFSET_DELAY_MAX_MSEC = 185,
97+
KEY_REPEAT_OFFSET_DELAY_STEP_MSEC = 15
9398
};
9499

95100
public:

GeneralsMD/Code/GameEngine/Source/GameClient/Input/Keyboard.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -204,59 +204,58 @@ void Keyboard::updateKeys( void )
204204
//-------------------------------------------------------------------------------------------------
205205
Bool Keyboard::checkKeyRepeat( void )
206206
{
207-
Bool retVal = FALSE;
208-
Int index = 0;
209-
Int key;
210-
211-
/** @todo we shouldn't think about repeating any keys while we
212-
don't have the focus */
213-
// if( currentFocus == FOCUS_OUT )
214-
// return FALSE;
207+
// @todo we shouldn't think about repeating any keys while we don't have the focus
215208

216-
// Find end of real keys for this frame
217-
while( m_keys[ index ].key != KEY_NONE )
218-
index++;
209+
Bool retVal = FALSE;
210+
size_t index = 0;
219211

220-
// Scan Keyboard status array for first key down
221-
// long enough to repeat
222-
for( key = 0; key < ARRAY_SIZE(m_keyStatus); key++ )
212+
for (size_t i = 0; i < ARRAY_SIZE(m_keys) - 1 && m_keys[i].key != KEY_NONE; ++i)
223213
{
214+
++index;
215+
}
224216

217+
// Scan keyboard status array for first key down long enough to repeat
218+
for( size_t key = 0; key < ARRAY_SIZE(m_keyStatus); ++key )
219+
{
225220
if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) )
226221
{
227-
228222
const UnsignedInt now = timeGetTime();
229-
const UnsignedInt keyDownTime = m_keyStatus[ key ].keyDownTimeMsec;
230-
const UnsignedInt elapsedMsec = now - keyDownTime;
231223

232-
if( elapsedMsec > Keyboard::KEY_REPEAT_DELAY_MSEC )
224+
if( m_keyStatus[ key ].keyDownTimeMsec > 0 && now - m_keyStatus[ key ].keyDownTimeMsec > Keyboard::KEY_REPEAT_DELAY_MSEC )
233225
{
234226
// Add key to this frame
235-
m_keys[ index ].key = (UnsignedByte)key;
236-
m_keys[ index ].state = KEY_STATE_DOWN | KEY_STATE_AUTOREPEAT; // note: not a bitset; this is an assignment
237-
m_keys[ index ].status = KeyboardIO::STATUS_UNUSED;
227+
if (index < ARRAY_SIZE(m_keys) - 2)
228+
{
229+
m_keys[index].key = (UnsignedByte)key;
230+
m_keys[index].state = KEY_STATE_DOWN | KEY_STATE_AUTOREPEAT; // note: not a bitset; this is an assignment
231+
m_keys[index].status = KeyboardIO::STATUS_UNUSED;
238232

239-
// Set End Flag
240-
m_keys[ ++index ].key = KEY_NONE;
233+
// Set end flag
234+
++index;
235+
m_keys[index].key = KEY_NONE;
236+
}
241237

242-
// Set all keys as new to prevent multiple keys repeating
243-
for( index = 0; index< NUM_KEYS; index++ )
244-
m_keyStatus[ index ].keyDownTimeMsec = now;
238+
// Decrease the delay between registered key strokes the longer a key is held down
239+
const UnsignedInt keyRepeatTimeMsecOffset = clamp(
240+
static_cast<UnsignedInt>(KEY_REPEAT_OFFSET_DELAY_STEP_MSEC) + m_keyStatus[ key ].keyRepeatTimeMsecOffset,
241+
static_cast<UnsignedInt>(KEY_REPEAT_OFFSET_DELAY_MIN_MSEC),
242+
static_cast<UnsignedInt>(KEY_REPEAT_OFFSET_DELAY_MAX_MSEC));
245243

246244
// Set repeated key so it will repeat again after the interval
247-
m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + Keyboard::KEY_REPEAT_INTERVAL_MSEC);
245+
m_keyStatus[ key ].keyRepeatTimeMsecOffset = keyRepeatTimeMsecOffset;
246+
m_keyStatus[ key ].keyDownTimeMsec = now - m_keyStatus[ key ].keyRepeatTimeMsecOffset;
248247

249248
retVal = TRUE;
250-
break; // exit for key
251-
252249
}
253-
254250
}
255-
251+
else
252+
{
253+
m_keyStatus[ key ].keyDownTimeMsec = 0;
254+
m_keyStatus[ key ].keyRepeatTimeMsecOffset = 0;
255+
}
256256
}
257257

258258
return retVal;
259-
260259
}
261260

262261
//-------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)