Ver código fonte

Fixed mixed trigger and body rumble for Xbox controllers on Windows

Fixes https://github.com/libsdl-org/SDL/issues/12095
Sam Lantinga 3 semanas atrás
pai
commit
b6ca03611f
1 arquivos alterados com 9 adições e 5 exclusões
  1. 9 5
      src/joystick/windows/SDL_rawinputjoystick.c

+ 9 - 5
src/joystick/windows/SDL_rawinputjoystick.c

@@ -160,6 +160,8 @@ struct joystick_hwdata
     WindowsGamingInputGamepadState *wgi_slot;
 #endif
 
+    bool triggers_rumbling;
+
     SDL_RAWINPUT_Device *device;
 };
 typedef struct joystick_hwdata RAWINPUT_DeviceContext;
@@ -1461,7 +1463,7 @@ static bool RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency
 
 #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
     // Prefer XInput over WGI because it allows rumble in the background
-    if (!rumbled && ctx->xinput_correlated) {
+    if (!rumbled && ctx->xinput_correlated && !ctx->triggers_rumbling) {
         XINPUT_VIBRATION XVibration;
 
         if (!XINPUTSETSTATE) {
@@ -1479,11 +1481,12 @@ static bool RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency
 #endif // SDL_JOYSTICK_RAWINPUT_XINPUT
 
 #ifdef SDL_JOYSTICK_RAWINPUT_WGI
+    // Save off the motor state in case trigger rumble is started
+    WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
+    HRESULT hr;
+    gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
+    gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
     if (!rumbled && ctx->wgi_correlated) {
-        WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
-        HRESULT hr;
-        gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
-        gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
         hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
         if (SUCCEEDED(hr)) {
             rumbled = true;
@@ -1515,6 +1518,7 @@ static bool RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_
         if (!SUCCEEDED(hr)) {
             return SDL_SetError("Setting vibration failed: 0x%lx", hr);
         }
+        ctx->triggers_rumbling = (left_rumble > 0 || right_rumble > 0);
         return true;
     } else {
         return SDL_SetError("Controller isn't correlated yet, try hitting a button first");