Pass the event timestamp for joystick events

This allows the application to get more fine grained information about controller event timing, and group events that happened together.
This commit is contained in:
Sam Lantinga 2022-12-03 11:15:50 -08:00
parent f32cdfa096
commit 73f4aeee6a
36 changed files with 950 additions and 839 deletions

View file

@ -1399,22 +1399,22 @@ static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int
};
Uint64 match_state = ctx->match_state;
/* Update match_state with button bit, then fall through */
#define SDL_PrivateJoystickButton(joystick, button, state) \
#define SDL_PrivateJoystickButton(timestamp, joystick, button, state) \
if (button < SDL_arraysize(button_map)) { \
Uint64 button_bit = 1ull << button_map[button]; \
match_state = (match_state & ~button_bit) | (button_bit * (state)); \
} \
SDL_PrivateJoystickButton(joystick, button, state)
SDL_PrivateJoystickButton(timestamp, joystick, button, state)
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
/* Grab high 4 bits of value, then fall through */
#define AddAxisToMatchState(axis, value) \
{ \
match_state = (match_state & ~(0xFull << (4 * axis + 16))) | ((value)&0xF000ull) << (4 * axis + 4); \
}
#define SDL_PrivateJoystickAxis(joystick, axis, value) \
#define SDL_PrivateJoystickAxis(timestamp, joystick, axis, value) \
if (axis < 4) \
AddAxisToMatchState(axis, value); \
SDL_PrivateJoystickAxis(joystick, axis, value)
SDL_PrivateJoystickAxis(timestamp, joystick, axis, value)
#endif
#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */
@ -1424,6 +1424,7 @@ static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int
int naxes = joystick->naxes - (ctx->trigger_hack * 2);
int nhats = joystick->nhats;
Uint32 button_mask = 0;
Uint64 timestamp = SDL_GetTicksNS();
if (SDL_HidP_GetData(HidP_Input, ctx->data, &data_length, ctx->preparsed_data, (PCHAR)data, size) != HIDP_STATUS_SUCCESS) {
return;
@ -1436,14 +1437,14 @@ static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int
}
}
for (i = 0; i < nbuttons; ++i) {
SDL_PrivateJoystickButton(joystick, i, (button_mask & (1 << i)) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(timestamp, joystick, i, (button_mask & (1 << i)) ? SDL_PRESSED : SDL_RELEASED);
}
for (i = 0; i < naxes; ++i) {
HIDP_DATA *item = GetData(ctx->axis_indices[i], ctx->data, data_length);
if (item) {
Sint16 axis = (int)(Uint16)item->RawValue - 0x8000;
SDL_PrivateJoystickAxis(joystick, i, axis);
SDL_PrivateJoystickAxis(timestamp, joystick, i, axis);
}
}
@ -1467,7 +1468,7 @@ static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int
#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
match_state = (match_state & ~HAT_MASK) | hat_map[state];
#endif
SDL_PrivateJoystickHat(joystick, i, hat_states[state]);
SDL_PrivateJoystickHat(timestamp, joystick, i, hat_states[state]);
}
}
}
@ -1521,8 +1522,8 @@ static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int
if (!has_trigger_data)
#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */
{
SDL_PrivateJoystickAxis(joystick, left_trigger, left_value);
SDL_PrivateJoystickAxis(joystick, right_trigger, right_value);
SDL_PrivateJoystickAxis(timestamp, joystick, left_trigger, left_value);
SDL_PrivateJoystickAxis(timestamp, joystick, right_trigger, right_value);
}
}
}
@ -1590,7 +1591,7 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
/* It gets left down if we were actually correlated incorrectly and it was released on the WindowsGamingInput
device but we didn't get a state packet. */
if (ctx->guide_hack) {
SDL_PrivateJoystickButton(joystick, guide_button, SDL_RELEASED);
SDL_PrivateJoystickButton(0, joystick, guide_button, SDL_RELEASED);
}
}
}
@ -1686,7 +1687,7 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
/* It gets left down if we were actually correlated incorrectly and it was released on the XInput
device but we didn't get a state packet. */
if (ctx->guide_hack) {
SDL_PrivateJoystickButton(joystick, guide_button, SDL_RELEASED);
SDL_PrivateJoystickButton(0, joystick, guide_button, SDL_RELEASED);
}
}
}
@ -1749,13 +1750,18 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
RAWINPUT_UpdateXInput();
if (xinput_state[ctx->xinput_slot].connected) {
XINPUT_BATTERY_INFORMATION_EX *battery_info = &xinput_state[ctx->xinput_slot].battery;
Uint64 timestamp;
if (ctx->guide_hack || ctx->trigger_hack) {
timestamp = SDL_GetTicksNS();
}
if (ctx->guide_hack) {
SDL_PrivateJoystickButton(joystick, guide_button, (xinput_state[ctx->xinput_slot].state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(timestamp, joystick, guide_button, (xinput_state[ctx->xinput_slot].state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->trigger_hack) {
SDL_PrivateJoystickAxis(joystick, left_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bLeftTrigger * 257) - 32768);
SDL_PrivateJoystickAxis(joystick, right_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bRightTrigger * 257) - 32768);
SDL_PrivateJoystickAxis(timestamp, joystick, left_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bLeftTrigger * 257) - 32768);
SDL_PrivateJoystickAxis(timestamp, joystick, right_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bRightTrigger * 257) - 32768);
}
has_trigger_data = SDL_TRUE;
@ -1792,13 +1798,18 @@ static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
RAWINPUT_UpdateWindowsGamingInput(); /* May detect disconnect / cause uncorrelation */
if (ctx->wgi_correlated) { /* Still connected */
struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading *state = &ctx->wgi_slot->state;
Uint64 timestamp;
if (ctx->guide_hack || ctx->trigger_hack) {
timestamp = SDL_GetTicksNS();
}
if (ctx->guide_hack) {
SDL_PrivateJoystickButton(joystick, guide_button, (state->Buttons & GamepadButtons_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
SDL_PrivateJoystickButton(timestamp, joystick, guide_button, (state->Buttons & GamepadButtons_GUIDE) ? SDL_PRESSED : SDL_RELEASED);
}
if (ctx->trigger_hack) {
SDL_PrivateJoystickAxis(joystick, left_trigger, ((int)(state->LeftTrigger * SDL_MAX_UINT16)) - 32768);
SDL_PrivateJoystickAxis(joystick, right_trigger, ((int)(state->RightTrigger * SDL_MAX_UINT16)) - 32768);
SDL_PrivateJoystickAxis(timestamp, joystick, left_trigger, ((int)(state->LeftTrigger * SDL_MAX_UINT16)) - 32768);
SDL_PrivateJoystickAxis(timestamp, joystick, right_trigger, ((int)(state->RightTrigger * SDL_MAX_UINT16)) - 32768);
}
has_trigger_data = SDL_TRUE;
}