Skip to content

Commit

Permalink
Make input events use earliest possible time
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
zturtleman committed Aug 22, 2017
1 parent 5993c63 commit 63e07af
Showing 1 changed file with 53 additions and 48 deletions.
101 changes: 53 additions & 48 deletions code/sdl/sdl_input.c
Expand Up @@ -51,6 +51,8 @@ static cvar_t *in_joystickUseAnalog = NULL;

static int vidRestartTime = 0;

static int in_eventTime = 0;

static SDL_Window *SDL_window = NULL;

#define CTRL(a) ((a)-'a'+1)
Expand Down Expand Up @@ -649,7 +651,7 @@ static void IN_GamepadMove( void )
qboolean pressed = SDL_GameControllerGetButton(gamepad, SDL_CONTROLLER_BUTTON_A + 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;
}
}
Expand Down Expand Up @@ -729,19 +731,19 @@ static void IN_GamepadMove( void )

// positive to negative/neutral -> keyup
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
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
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
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;
}
Expand All @@ -753,7 +755,7 @@ static void IN_GamepadMove( void )
for (i = 0; i < MAX_JOYSTICK_AXIS; 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);
}
}
}
Expand Down Expand Up @@ -804,7 +806,7 @@ static void IN_JoyMove( void )
balldx *= 2;
if (abs(balldy) > 1)
balldy *= 2;
Com_QueueEvent( 0, SE_MOUSE, balldx, balldy, 0, NULL );
Com_QueueEvent( in_eventTime, SE_MOUSE, balldx, balldy, 0, NULL );
}
}

Expand All @@ -819,7 +821,7 @@ static void IN_JoyMove( void )
qboolean pressed = (SDL_JoystickGetButton(stick, i) != 0);
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;
}
}
Expand All @@ -844,65 +846,65 @@ static void IN_JoyMove( void )
// release event
switch( ((Uint8 *)&stick_state.oldhats)[i] ) {
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;
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;
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;
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;
case SDL_HAT_RIGHTUP:
Com_QueueEvent( 0, 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 + 0], qfalse, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
break;
case SDL_HAT_RIGHTDOWN:
Com_QueueEvent( 0, 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 + 2], qfalse, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
break;
case SDL_HAT_LEFTUP:
Com_QueueEvent( 0, 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 + 0], qfalse, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
break;
case SDL_HAT_LEFTDOWN:
Com_QueueEvent( 0, 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 + 2], qfalse, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
break;
default:
break;
}
// press event
switch( ((Uint8 *)&hats)[i] ) {
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;
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;
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;
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;
case SDL_HAT_RIGHTUP:
Com_QueueEvent( 0, 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 + 0], qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
break;
case SDL_HAT_RIGHTDOWN:
Com_QueueEvent( 0, 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 + 2], qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
break;
case SDL_HAT_LEFTUP:
Com_QueueEvent( 0, 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 + 0], qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
break;
case SDL_HAT_LEFTDOWN:
Com_QueueEvent( 0, 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 + 2], qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
break;
default:
break;
Expand Down Expand Up @@ -930,7 +932,7 @@ static void IN_JoyMove( void )

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;
}
}
Expand All @@ -956,11 +958,11 @@ static void IN_JoyMove( void )
{
for( i = 0; i < 16; 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 ) ) ) {
Com_QueueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, joy_keys[i], qfalse, 0, NULL );
}
}
}
Expand Down Expand Up @@ -992,19 +994,19 @@ static void IN_ProcessEvents( void )
break;

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 )
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' )
Com_QueueEvent( 0, SE_CHAR, CTRL(key), 0, 0, NULL );
Com_QueueEvent( in_eventTime, SE_CHAR, CTRL(key), 0, 0, NULL );

lastKeyDown = key;
break;

case SDL_KEYUP:
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;
break;
Expand Down Expand Up @@ -1049,11 +1051,11 @@ static void IN_ProcessEvents( void )
{
if( IN_IsConsoleKey( 0, utf32 ) )
{
Com_QueueEvent( 0, 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, qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, K_CONSOLE, qfalse, 0, NULL );
}
else
Com_QueueEvent( 0, SE_CHAR, utf32, 0, 0, NULL );
Com_QueueEvent( in_eventTime, SE_CHAR, utf32, 0, 0, NULL );
}
}
}
Expand All @@ -1064,7 +1066,7 @@ static void IN_ProcessEvents( void )
{
if( !e.motion.xrel && !e.motion.yrel )
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;

Expand All @@ -1081,21 +1083,21 @@ static void IN_ProcessEvents( void )
case SDL_BUTTON_X2: b = K_MOUSE5; 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 );
}
break;

case SDL_MOUSEWHEEL:
if( e.wheel.y > 0 )
{
Com_QueueEvent( 0, 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, qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
}
else if( e.wheel.y < 0 )
{
Com_QueueEvent( 0, 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, qtrue, 0, NULL );
Com_QueueEvent( in_eventTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
}
break;

Expand Down Expand Up @@ -1184,6 +1186,9 @@ void IN_Frame( void )

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
if( ( vidRestartTime != 0 ) && ( vidRestartTime < Sys_Milliseconds( ) ) )
{
Expand Down

0 comments on commit 63e07af

Please sign in to comment.