Skip to content

Commit 1f2c1a3

Browse files
authored
bugfix(input): Replace frame-based timings with real-time timings in input system (#1835)
1 parent 529675f commit 1f2c1a3

File tree

18 files changed

+128
-218
lines changed

18 files changed

+128
-218
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct KeyboardIO
7676
UnsignedByte key; // KeyDefType, key data
7777
UnsignedByte status; // StatusType, above
7878
UnsignedShort state; // KEY_STATE_* in KeyDefs.h
79-
UnsignedInt sequence; // sequence info from DirectX used for order
79+
UnsignedInt keyDownTimeMsec; // real-time in milliseconds when key went down
8080

8181
};
8282

@@ -86,7 +86,11 @@ struct KeyboardIO
8686
class Keyboard : public SubsystemInterface
8787
{
8888

89-
enum { KEY_REPEAT_DELAY = 10 };
89+
enum
90+
{
91+
KEY_REPEAT_DELAY_MSEC = 333, // 10 frames at 30 FPS
92+
KEY_REPEAT_INTERVAL_MSEC = 67 // ~2 frames at 30 FPS
93+
};
9094

9195
public:
9296

@@ -133,7 +137,6 @@ class Keyboard : public SubsystemInterface
133137
Bool checkKeyRepeat( void ); ///< check for repeating keys
134138
UnsignedByte getKeyStatusData( KeyDefType key ); ///< get key status
135139
Bool getKeyStateBit( KeyDefType key, Int bit ); ///< get key state bit
136-
UnsignedInt getKeySequenceData( KeyDefType key ); ///< get key sequence
137140
void setKeyStateData( KeyDefType key, UnsignedByte data ); ///< get key state
138141

139142
UnsignedShort m_modifiers;
@@ -161,7 +164,6 @@ class Keyboard : public SubsystemInterface
161164
WideChar shifted2;
162165

163166
} m_keyNames[ KEY_COUNT ];
164-
UnsignedInt m_inputFrame; ///< frame input was gathered on
165167

166168
};
167169

Generals/Code/GameEngine/Include/GameClient/LookAtXlat.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ class LookAtTranslator : public GameMessageTranslator
7676
Bool m_isRotating; // set to true if we are in the act of MMB rotating
7777
Bool m_isPitching; // set to true if we are in the act of ALT pitch rotation
7878
Bool m_isChangingFOV; // set to true if we are in the act of changing the field of view
79-
UnsignedInt m_timestamp; // set when button goes down
79+
UnsignedInt m_middleButtonDownTimeMsec; // real-time in milliseconds when middle button goes down
8080
DrawableID m_lastPlaneID;
8181
ViewLocation m_viewLocation[ MAX_VIEW_LOCS ];
8282
ScrollType m_scrollType;
8383
ScreenEdgeScrollMode m_screenEdgeScrollMode;
84-
UnsignedInt m_lastMouseMoveFrame;
84+
UnsignedInt m_lastMouseMoveTimeMsec; // real-time in milliseconds when mouse last moved
8585

8686
void setScrolling( ScrollType scrollType );
8787
void stopScrolling( void );

Generals/Code/GameEngine/Include/GameClient/Mouse.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum GameMode CPP_11(: Int);
6262

6363
enum MouseButtonState CPP_11(: Int)
6464
{
65+
MBS_None = -1,
6566
MBS_Up = 0,
6667
MBS_Down,
6768
MBS_DoubleClick,
@@ -105,17 +106,14 @@ struct MouseIO
105106
user while - is down/toward user */
106107
ICoord2D deltaPos; ///< overall change in mouse pointer this frame
107108

108-
MouseButtonState leftState; // button state: Up, Down, DoubleClick (Which is also down)
109+
MouseButtonState leftState; // button state: None (no event), Up, Down, DoubleClick
109110
Int leftEvent; // Most important event this frame
110-
Int leftFrame; // last frame button state changed
111111

112112
MouseButtonState rightState;
113113
Int rightEvent;
114-
Int rightFrame;
115114

116115
MouseButtonState middleState;
117116
Int middleEvent;
118-
Int middleFrame;
119117
};
120118

121119
class CursorInfo
@@ -393,9 +391,6 @@ class Mouse : public SubsystemInterface
393391
Int m_minY; ///< mouse is locked to this region
394392
Int m_maxY; ///< mouse is locked to this region
395393

396-
UnsignedInt m_inputFrame; ///< frame input was gathered on
397-
UnsignedInt m_deadInputFrame; ///< Frame which last input occured
398-
399394
Bool m_inputMovesAbsolute; /**< if TRUE, when processing mouse position
400395
chanages the movement will be done treating
401396
the coords as ABSOLUTE positions and NOT

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

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,12 @@ void Keyboard::updateKeys( void )
140140

141141
m_keyStatus[ m_keys[ index ].key ].state = m_keys[ index ].state;
142142
m_keyStatus[ m_keys[ index ].key ].status = m_keys[ index ].status;
143-
m_keyStatus[ m_keys[ index ].key ].sequence = m_inputFrame;
143+
144+
// Update key down time for new key presses
145+
if( BitIsSet( m_keys[ index ].state, KEY_STATE_DOWN ) )
146+
{
147+
m_keyStatus[ m_keys[ index ].key ].keyDownTimeMsec = m_keys[ index ].keyDownTimeMsec;
148+
}
144149

145150
// prevent ALT-TAB from causing a TAB event
146151
if( m_keys[ index ].key == KEY_TAB )
@@ -195,7 +200,7 @@ void Keyboard::updateKeys( void )
195200
}
196201

197202
//-------------------------------------------------------------------------------------------------
198-
/** check key repeat sequences, TRUE is returned if repeat is occurring */
203+
/** check key repeat timing, TRUE is returned if repeat is occurring */
199204
//-------------------------------------------------------------------------------------------------
200205
Bool Keyboard::checkKeyRepeat( void )
201206
{
@@ -220,7 +225,13 @@ Bool Keyboard::checkKeyRepeat( void )
220225
if( BitIsSet( m_keyStatus[ key ].state, KEY_STATE_DOWN ) )
221226
{
222227

223-
if( (m_inputFrame - m_keyStatus[ key ].sequence) > Keyboard::KEY_REPEAT_DELAY )
228+
const UnsignedInt now = timeGetTime();
229+
const UnsignedInt keyDownTime = m_keyStatus[ key ].keyDownTimeMsec;
230+
231+
// Unsigned subtraction handles wraparound correctly
232+
const UnsignedInt elapsedMsec = now - keyDownTime;
233+
234+
if( elapsedMsec > Keyboard::KEY_REPEAT_DELAY_MSEC )
224235
{
225236
// Add key to this frame
226237
m_keys[ index ].key = (UnsignedByte)key;
@@ -232,10 +243,10 @@ Bool Keyboard::checkKeyRepeat( void )
232243

233244
// Set all keys as new to prevent multiple keys repeating
234245
for( index = 0; index< NUM_KEYS; index++ )
235-
m_keyStatus[ index ].sequence = m_inputFrame;
246+
m_keyStatus[ index ].keyDownTimeMsec = now;
236247

237-
// Set repeated key so it will repeat again in two frames
238-
m_keyStatus[ key ].sequence = m_inputFrame - (Keyboard::KEY_REPEAT_DELAY + 2);
248+
// Set repeated key so it will repeat again after the interval
249+
m_keyStatus[ key ].keyDownTimeMsec = now - (Keyboard::KEY_REPEAT_DELAY_MSEC + Keyboard::KEY_REPEAT_INTERVAL_MSEC);
239250

240251
retVal = TRUE;
241252
break; // exit for key
@@ -694,7 +705,6 @@ Keyboard::Keyboard( void )
694705
m_shift2Key = KEY_NONE;
695706

696707
memset( m_keyNames, 0, sizeof( m_keyNames ) );
697-
m_inputFrame = 0;
698708

699709
}
700710

@@ -714,9 +724,6 @@ void Keyboard::init( void )
714724
// initialize the key names
715725
initKeyNames();
716726

717-
// first input frame
718-
m_inputFrame = 0;
719-
720727
}
721728

722729
//-------------------------------------------------------------------------------------------------
@@ -733,9 +740,6 @@ void Keyboard::reset( void )
733740
void Keyboard::update( void )
734741
{
735742

736-
// increment input frame
737-
m_inputFrame++;
738-
739743
// update the key data
740744
updateKeys();
741745

@@ -819,14 +823,6 @@ Bool Keyboard::getKeyStateBit( KeyDefType key, Int bit )
819823
return (m_keyStatus[ key ].state & bit) ? 1 : 0;
820824
}
821825

822-
//-------------------------------------------------------------------------------------------------
823-
/** return the sequence data for the given key */
824-
//-------------------------------------------------------------------------------------------------
825-
UnsignedInt Keyboard::getKeySequenceData( KeyDefType key )
826-
{
827-
return m_keyStatus[ key ].sequence;
828-
}
829-
830826
//-------------------------------------------------------------------------------------------------
831827
/** set the key status data */
832828
//-------------------------------------------------------------------------------------------------

Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,6 @@ void Mouse::updateMouseData( )
183183
else
184184
m_eventsThisFrame = 0;
185185

186-
if( index != 0 )
187-
m_deadInputFrame = m_inputFrame;
188-
189186
}
190187

191188
//-------------------------------------------------------------------------------------------------
@@ -221,7 +218,7 @@ void Mouse::processMouseEvent( Int index )
221218
m_currMouse.wheelPos += m_mouseEvents[ index ].wheelPos;
222219

223220
// Check Left Mouse State
224-
if( m_mouseEvents[ index ].leftFrame )
221+
if( m_mouseEvents[ index ].leftState != MBS_None )
225222
{
226223
if( m_currMouse.leftState != m_mouseEvents[ index ].leftState )
227224
{
@@ -231,21 +228,18 @@ void Mouse::processMouseEvent( Int index )
231228
// Mouse Down
232229
m_currMouse.leftEvent = GWM_LEFT_DOWN;
233230
m_currMouse.leftState = MBS_Down;
234-
m_currMouse.leftFrame = m_inputFrame;
235231
}
236232
else if ( m_mouseEvents[ index ].leftState == MBS_DoubleClick )
237233
{
238234
// Mouse Double Click
239235
m_currMouse.leftEvent = GWM_LEFT_DOUBLE_CLICK;
240236
m_currMouse.leftState = MBS_DoubleClick;
241-
m_currMouse.leftFrame = m_inputFrame;
242237
}
243238
else
244239
{
245240
// Mouse Up
246241
m_currMouse.leftEvent = GWM_LEFT_UP;
247242
m_currMouse.leftState = MBS_Up;
248-
m_currMouse.leftFrame = m_inputFrame;
249243
}
250244
}
251245
}
@@ -257,7 +251,7 @@ void Mouse::processMouseEvent( Int index )
257251
}
258252

259253
// Check Right Mouse State
260-
if( m_mouseEvents[ index ].rightFrame )
254+
if( m_mouseEvents[ index ].rightState != MBS_None )
261255
{
262256
if( m_currMouse.rightState != m_mouseEvents[ index ].rightState )
263257
{
@@ -267,21 +261,18 @@ void Mouse::processMouseEvent( Int index )
267261
// Mouse Down
268262
m_currMouse.rightEvent = GWM_RIGHT_DOWN;
269263
m_currMouse.rightState = MBS_Down;
270-
m_currMouse.rightFrame = m_inputFrame;
271264
}
272265
else if( m_mouseEvents[ index ].rightState == MBS_DoubleClick )
273266
{
274267
// Mouse Double Click
275268
m_currMouse.rightEvent = GWM_RIGHT_DOUBLE_CLICK;
276269
m_currMouse.rightState = MBS_DoubleClick;
277-
m_currMouse.rightFrame = m_inputFrame;
278270
}
279271
else
280272
{
281273
// Mouse Up
282274
m_currMouse.rightEvent = GWM_RIGHT_UP;
283275
m_currMouse.rightState = MBS_Up;
284-
m_currMouse.rightFrame = m_inputFrame;
285276
}
286277
}
287278
}
@@ -293,7 +284,7 @@ void Mouse::processMouseEvent( Int index )
293284
}
294285

295286
// Check Middle Mouse State
296-
if( m_mouseEvents[ index ].middleFrame )
287+
if( m_mouseEvents[ index ].middleState != MBS_None )
297288
{
298289
if( m_currMouse.middleState != m_mouseEvents[index].middleState )
299290
{
@@ -302,20 +293,17 @@ void Mouse::processMouseEvent( Int index )
302293
{
303294
m_currMouse.middleEvent = GWM_MIDDLE_DOWN;
304295
m_currMouse.middleState = MBS_Down;
305-
m_currMouse.middleFrame = m_inputFrame;
306296
}
307297
else if( m_mouseEvents[index].middleState == MBS_DoubleClick )
308298
{
309299
m_currMouse.middleEvent = GWM_MIDDLE_DOUBLE_CLICK;
310300
m_currMouse.middleState = MBS_DoubleClick;
311-
m_currMouse.middleFrame = m_inputFrame;
312301
}
313302
else
314303
{
315304
// Mouse Up
316305
m_currMouse.middleEvent = GWM_MIDDLE_UP;
317306
m_currMouse.middleState = MBS_Up;
318-
m_currMouse.middleFrame = m_inputFrame;
319307
}
320308
}
321309
}
@@ -328,7 +316,7 @@ void Mouse::processMouseEvent( Int index )
328316

329317
m_currMouse.deltaPos.x = m_currMouse.pos.x - m_prevMouse.pos.x;
330318
m_currMouse.deltaPos.y = m_currMouse.pos.y - m_prevMouse.pos.y;
331-
// DEBUG_LOG(("Mouse dx %d, dy %d, index %d, frame %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index, m_inputFrame));
319+
// DEBUG_LOG(("Mouse dx %d, dy %d, index %d", m_currMouse.deltaPos.x, m_currMouse.deltaPos.y, index));
332320
// // check if mouse is still and flag tooltip
333321
// if( ((dx*dx) + (dy*dy)) < CURSOR_MOVE_TOL_SQ )
334322
// {
@@ -474,9 +462,6 @@ Mouse::Mouse( void )
474462
m_maxY = 0;
475463
m_eventsThisFrame = 0;
476464

477-
m_inputFrame = 0;
478-
m_deadInputFrame =0;
479-
480465
m_inputMovesAbsolute = FALSE;
481466

482467
m_currentCursor = ARROW;
@@ -590,9 +575,6 @@ void Mouse::init( void )
590575
m_minY = 0;
591576
m_maxY = 599;
592577

593-
m_inputFrame = 0;
594-
m_deadInputFrame =0;
595-
596578
m_inputMovesAbsolute = FALSE;
597579
m_eventsThisFrame = 0;
598580

@@ -676,9 +658,6 @@ void Mouse::reset( void )
676658
void Mouse::update( void )
677659
{
678660

679-
// increment input frame
680-
m_inputFrame++;
681-
682661
// update the mouse data
683662
updateMouseData( );
684663

0 commit comments

Comments
 (0)