From b7e65a81f1b0638c084d3c4195a7b88fb7175b6c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 11 Nov 2022 08:57:07 -0800 Subject: [PATCH] Fixed incorrect WGI controller state when the application loses focus Recenter the controller elements when WGI stops reporting valid state Fixes https://github.com/libsdl-org/SDL/issues/5261 --- src/joystick/SDL_joystick.c | 2 +- src/joystick/SDL_joystick_c.h | 1 + .../windows/SDL_windows_gaming_input.c | 26 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index c1e47beb0..c6d2bf393 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1432,7 +1432,7 @@ static void UpdateEventsForDeviceRemoval(int device_index, Uint32 type) SDL_small_free(events, isstack); } -static void +void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick) { int i, j; diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 3ded9763e..0f2093caf 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -152,6 +152,7 @@ extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers) extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate); extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance); extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance); +extern void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick); extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value); extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index deec84bf5..3a89d1154 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -852,15 +852,27 @@ WGI_JoystickUpdate(SDL_Joystick *joystick) hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_GetCurrentReading(hwdata->controller, nbuttons, buttons, nhats, hats, naxes, axes, ×tamp); if (SUCCEEDED(hr) && timestamp != hwdata->timestamp) { UINT32 i; + SDL_bool all_zero = SDL_TRUE; - for (i = 0; i < nbuttons; ++i) { - SDL_PrivateJoystickButton(joystick, (Uint8)i, buttons[i]); - } - for (i = 0; i < nhats; ++i) { - SDL_PrivateJoystickHat(joystick, (Uint8)i, ConvertHatValue(hats[i])); - } + /* The axes are all zero when the application loses focus */ for (i = 0; i < naxes; ++i) { - SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)((int) (axes[i] * 65535) - 32768)); + if (axes[i] != 0.0f) { + all_zero = SDL_FALSE; + break; + } + } + if (all_zero) { + SDL_PrivateJoystickForceRecentering(joystick); + } else { + for (i = 0; i < nbuttons; ++i) { + SDL_PrivateJoystickButton(joystick, (Uint8) i, buttons[i]); + } + for (i = 0; i < nhats; ++i) { + SDL_PrivateJoystickHat(joystick, (Uint8) i, ConvertHatValue(hats[i])); + } + for (i = 0; i < naxes; ++i) { + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)((int) (axes[i] * 65535) - 32768)); + } } hwdata->timestamp = timestamp; }