Make input events use earliest possible time

SDL doesn't provide exact the exact time that input events happen
so use the earliest possible time that an event could happen.

This make sub-frame input actions such as walking take affect
immediately instead of in the next frame.

Based on patch by Alexander "wareya" Nadeau.
This commit is contained in:
Zack Middleton 2017-08-21 22:30:32 -05:00
parent 5993c63c4e
commit 63e07afae9

View file

@ -51,6 +51,8 @@ static cvar_t *in_joystickUseAnalog = NULL;
static int vidRestartTime = 0; static int vidRestartTime = 0;
static int in_eventTime = 0;
static SDL_Window *SDL_window = NULL; static SDL_Window *SDL_window = NULL;
#define CTRL(a) ((a)-'a'+1) #define CTRL(a) ((a)-'a'+1)
@ -649,7 +651,7 @@ static void IN_GamepadMove( void )
qboolean pressed = SDL_GameControllerGetButton(gamepad, SDL_CONTROLLER_BUTTON_A + i); qboolean pressed = SDL_GameControllerGetButton(gamepad, SDL_CONTROLLER_BUTTON_A + i);
if (pressed != stick_state.buttons[i]) if (pressed != stick_state.buttons[i])
{ {
Com_QueueEvent(0, SE_KEY, K_PAD0_A + i, pressed, 0, NULL); Com_QueueEvent(in_eventTime, SE_KEY, K_PAD0_A + i, pressed, 0, NULL);
stick_state.buttons[i] = pressed; stick_state.buttons[i] = pressed;
} }
} }
@ -729,19 +731,19 @@ static void IN_GamepadMove( void )
// positive to negative/neutral -> keyup // positive to negative/neutral -> keyup
if (!posAnalog && posKey && oldAxis > 0 && axis <= 0) if (!posAnalog && posKey && oldAxis > 0 && axis <= 0)
Com_QueueEvent(0, SE_KEY, posKey, qfalse, 0, NULL); Com_QueueEvent(in_eventTime, SE_KEY, posKey, qfalse, 0, NULL);
// negative to positive/neutral -> keyup // negative to positive/neutral -> keyup
if (!negAnalog && negKey && oldAxis < 0 && axis >= 0) if (!negAnalog && negKey && oldAxis < 0 && axis >= 0)
Com_QueueEvent(0, SE_KEY, negKey, qfalse, 0, NULL); Com_QueueEvent(in_eventTime, SE_KEY, negKey, qfalse, 0, NULL);
// negative/neutral to positive -> keydown // negative/neutral to positive -> keydown
if (!posAnalog && posKey && oldAxis <= 0 && axis > 0) if (!posAnalog && posKey && oldAxis <= 0 && axis > 0)
Com_QueueEvent(0, SE_KEY, posKey, qtrue, 0, NULL); Com_QueueEvent(in_eventTime, SE_KEY, posKey, qtrue, 0, NULL);
// positive/neutral to negative -> keydown // positive/neutral to negative -> keydown
if (!negAnalog && negKey && oldAxis >= 0 && axis < 0) if (!negAnalog && negKey && oldAxis >= 0 && axis < 0)
Com_QueueEvent(0, SE_KEY, negKey, qtrue, 0, NULL); Com_QueueEvent(in_eventTime, SE_KEY, negKey, qtrue, 0, NULL);
stick_state.oldaaxes[i] = axis; stick_state.oldaaxes[i] = axis;
} }
@ -753,7 +755,7 @@ static void IN_GamepadMove( void )
for (i = 0; i < MAX_JOYSTICK_AXIS; i++) for (i = 0; i < MAX_JOYSTICK_AXIS; i++)
{ {
if (translatedAxesSet[i]) if (translatedAxesSet[i])
Com_QueueEvent(0, SE_JOYSTICK_AXIS, i, translatedAxes[i], 0, NULL); Com_QueueEvent(in_eventTime, SE_JOYSTICK_AXIS, i, translatedAxes[i], 0, NULL);
} }
} }
} }
@ -804,7 +806,7 @@ static void IN_JoyMove( void )
balldx *= 2; balldx *= 2;
if (abs(balldy) > 1) if (abs(balldy) > 1)
balldy *= 2; balldy *= 2;
Com_QueueEvent( 0, SE_MOUSE, balldx, balldy, 0, NULL ); Com_QueueEvent( in_eventTime, SE_MOUSE, balldx, balldy, 0, NULL );
} }
} }
@ -819,7 +821,7 @@ static void IN_JoyMove( void )
qboolean pressed = (SDL_JoystickGetButton(stick, i) != 0); qboolean pressed = (SDL_JoystickGetButton(stick, i) != 0);
if (pressed != stick_state.buttons[i]) if (pressed != stick_state.buttons[i])
{ {
Com_QueueEvent( 0, SE_KEY, K_JOY1 + i, pressed, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_JOY1 + i, pressed, 0, NULL );
stick_state.buttons[i] = pressed; stick_state.buttons[i] = pressed;
} }
} }
@ -844,32 +846,32 @@ static void IN_JoyMove( void )
// release event // release event
switch( ((Uint8 *)&stick_state.oldhats)[i] ) { switch( ((Uint8 *)&stick_state.oldhats)[i] ) {
case SDL_HAT_UP: case SDL_HAT_UP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
break; break;
case SDL_HAT_RIGHT: case SDL_HAT_RIGHT:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
break; break;
case SDL_HAT_DOWN: case SDL_HAT_DOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
break; break;
case SDL_HAT_LEFT: case SDL_HAT_LEFT:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
break; break;
case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHTUP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
break; break;
case SDL_HAT_RIGHTDOWN: case SDL_HAT_RIGHTDOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
break; break;
case SDL_HAT_LEFTUP: case SDL_HAT_LEFTUP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
break; break;
case SDL_HAT_LEFTDOWN: case SDL_HAT_LEFTDOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
break; break;
default: default:
break; break;
@ -877,32 +879,32 @@ static void IN_JoyMove( void )
// press event // press event
switch( ((Uint8 *)&hats)[i] ) { switch( ((Uint8 *)&hats)[i] ) {
case SDL_HAT_UP: case SDL_HAT_UP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
break; break;
case SDL_HAT_RIGHT: case SDL_HAT_RIGHT:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
break; break;
case SDL_HAT_DOWN: case SDL_HAT_DOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
break; break;
case SDL_HAT_LEFT: case SDL_HAT_LEFT:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
break; break;
case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHTUP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
break; break;
case SDL_HAT_RIGHTDOWN: case SDL_HAT_RIGHTDOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
break; break;
case SDL_HAT_LEFTUP: case SDL_HAT_LEFTUP:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
break; break;
case SDL_HAT_LEFTDOWN: case SDL_HAT_LEFTDOWN:
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
break; break;
default: default:
break; break;
@ -930,7 +932,7 @@ static void IN_JoyMove( void )
if ( axis != stick_state.oldaaxes[i] ) if ( axis != stick_state.oldaaxes[i] )
{ {
Com_QueueEvent( 0, SE_JOYSTICK_AXIS, i, axis, 0, NULL ); Com_QueueEvent( in_eventTime, SE_JOYSTICK_AXIS, i, axis, 0, NULL );
stick_state.oldaaxes[i] = axis; stick_state.oldaaxes[i] = axis;
} }
} }
@ -956,11 +958,11 @@ static void IN_JoyMove( void )
{ {
for( i = 0; i < 16; i++ ) { for( i = 0; i < 16; i++ ) {
if( ( axes & ( 1 << i ) ) && !( stick_state.oldaxes & ( 1 << i ) ) ) { if( ( axes & ( 1 << i ) ) && !( stick_state.oldaxes & ( 1 << i ) ) ) {
Com_QueueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, joy_keys[i], qtrue, 0, NULL );
} }
if( !( axes & ( 1 << i ) ) && ( stick_state.oldaxes & ( 1 << i ) ) ) { if( !( axes & ( 1 << i ) ) && ( stick_state.oldaxes & ( 1 << i ) ) ) {
Com_QueueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, joy_keys[i], qfalse, 0, NULL );
} }
} }
} }
@ -992,19 +994,19 @@ static void IN_ProcessEvents( void )
break; break;
if( ( key = IN_TranslateSDLToQ3Key( &e.key.keysym, qtrue ) ) ) if( ( key = IN_TranslateSDLToQ3Key( &e.key.keysym, qtrue ) ) )
Com_QueueEvent( 0, SE_KEY, key, qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, key, qtrue, 0, NULL );
if( key == K_BACKSPACE ) if( key == K_BACKSPACE )
Com_QueueEvent( 0, SE_CHAR, CTRL('h'), 0, 0, NULL ); Com_QueueEvent( in_eventTime, SE_CHAR, CTRL('h'), 0, 0, NULL );
else if( keys[K_CTRL].down && key >= 'a' && key <= 'z' ) else if( keys[K_CTRL].down && key >= 'a' && key <= 'z' )
Com_QueueEvent( 0, SE_CHAR, CTRL(key), 0, 0, NULL ); Com_QueueEvent( in_eventTime, SE_CHAR, CTRL(key), 0, 0, NULL );
lastKeyDown = key; lastKeyDown = key;
break; break;
case SDL_KEYUP: case SDL_KEYUP:
if( ( key = IN_TranslateSDLToQ3Key( &e.key.keysym, qfalse ) ) ) if( ( key = IN_TranslateSDLToQ3Key( &e.key.keysym, qfalse ) ) )
Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, key, qfalse, 0, NULL );
lastKeyDown = 0; lastKeyDown = 0;
break; break;
@ -1049,11 +1051,11 @@ static void IN_ProcessEvents( void )
{ {
if( IN_IsConsoleKey( 0, utf32 ) ) if( IN_IsConsoleKey( 0, utf32 ) )
{ {
Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_CONSOLE, qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, K_CONSOLE, qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_CONSOLE, qfalse, 0, NULL );
} }
else else
Com_QueueEvent( 0, SE_CHAR, utf32, 0, 0, NULL ); Com_QueueEvent( in_eventTime, SE_CHAR, utf32, 0, 0, NULL );
} }
} }
} }
@ -1064,7 +1066,7 @@ static void IN_ProcessEvents( void )
{ {
if( !e.motion.xrel && !e.motion.yrel ) if( !e.motion.xrel && !e.motion.yrel )
break; break;
Com_QueueEvent( 0, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL ); Com_QueueEvent( in_eventTime, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL );
} }
break; break;
@ -1081,7 +1083,7 @@ static void IN_ProcessEvents( void )
case SDL_BUTTON_X2: b = K_MOUSE5; break; case SDL_BUTTON_X2: b = K_MOUSE5; break;
default: b = K_AUX1 + ( e.button.button - SDL_BUTTON_X2 + 1 ) % 16; break; default: b = K_AUX1 + ( e.button.button - SDL_BUTTON_X2 + 1 ) % 16; break;
} }
Com_QueueEvent( 0, SE_KEY, b, Com_QueueEvent( in_eventTime, SE_KEY, b,
( e.type == SDL_MOUSEBUTTONDOWN ? qtrue : qfalse ), 0, NULL ); ( e.type == SDL_MOUSEBUTTONDOWN ? qtrue : qfalse ), 0, NULL );
} }
break; break;
@ -1089,13 +1091,13 @@ static void IN_ProcessEvents( void )
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
if( e.wheel.y > 0 ) if( e.wheel.y > 0 )
{ {
Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
} }
else if( e.wheel.y < 0 ) else if( e.wheel.y < 0 )
{ {
Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
} }
break; break;
@ -1184,6 +1186,9 @@ void IN_Frame( void )
IN_ProcessEvents( ); IN_ProcessEvents( );
// Set event time for next frame to earliest possible time an event could happen
in_eventTime = Sys_Milliseconds( );
// In case we had to delay actual restart of video system // In case we had to delay actual restart of video system
if( ( vidRestartTime != 0 ) && ( vidRestartTime < Sys_Milliseconds( ) ) ) if( ( vidRestartTime != 0 ) && ( vidRestartTime < Sys_Milliseconds( ) ) )
{ {