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
This commit is contained in:
Sam Lantinga 2022-11-11 08:57:07 -08:00
parent 875e9b35d7
commit b7e65a81f1
3 changed files with 21 additions and 8 deletions

View File

@ -1432,7 +1432,7 @@ static void UpdateEventsForDeviceRemoval(int device_index, Uint32 type)
SDL_small_free(events, isstack); SDL_small_free(events, isstack);
} }
static void void
SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick) SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick)
{ {
int i, j; int i, j;

View File

@ -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_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate);
extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance); extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance);
extern void SDL_PrivateJoystickRemoved(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, extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick,
Uint8 axis, Sint16 value); Uint8 axis, Sint16 value);
extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick,

View File

@ -852,16 +852,28 @@ WGI_JoystickUpdate(SDL_Joystick *joystick)
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_GetCurrentReading(hwdata->controller, nbuttons, buttons, nhats, hats, naxes, axes, &timestamp); hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_GetCurrentReading(hwdata->controller, nbuttons, buttons, nhats, hats, naxes, axes, &timestamp);
if (SUCCEEDED(hr) && timestamp != hwdata->timestamp) { if (SUCCEEDED(hr) && timestamp != hwdata->timestamp) {
UINT32 i; UINT32 i;
SDL_bool all_zero = SDL_TRUE;
/* The axes are all zero when the application loses focus */
for (i = 0; i < naxes; ++i) {
if (axes[i] != 0.0f) {
all_zero = SDL_FALSE;
break;
}
}
if (all_zero) {
SDL_PrivateJoystickForceRecentering(joystick);
} else {
for (i = 0; i < nbuttons; ++i) { for (i = 0; i < nbuttons; ++i) {
SDL_PrivateJoystickButton(joystick, (Uint8)i, buttons[i]); SDL_PrivateJoystickButton(joystick, (Uint8) i, buttons[i]);
} }
for (i = 0; i < nhats; ++i) { for (i = 0; i < nhats; ++i) {
SDL_PrivateJoystickHat(joystick, (Uint8)i, ConvertHatValue(hats[i])); SDL_PrivateJoystickHat(joystick, (Uint8) i, ConvertHatValue(hats[i]));
} }
for (i = 0; i < naxes; ++i) { for (i = 0; i < naxes; ++i) {
SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)((int) (axes[i] * 65535) - 32768)); SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)((int) (axes[i] * 65535) - 32768));
} }
}
hwdata->timestamp = timestamp; hwdata->timestamp = timestamp;
} }