From 20d67446e023b9204cc8eaef6338269388ebb9b3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 27 Feb 2020 09:33:32 -0800 Subject: [PATCH] Xbox One controller rumble doesn't need synchronization if you use a packet counter of 0 --- src/joystick/hidapi/SDL_hidapi_xboxone.c | 87 ++---------------------- 1 file changed, 5 insertions(+), 82 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 2e109c901..593cd6568 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -74,11 +74,6 @@ static const Uint8 xboxone_init6[] = { 0x00, 0x00, 0xFF, 0x00, 0xEB }; -static const Uint8 xboxone_rumble_reset[] = { - 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 -}; - /* * This specifies the selection of init packets that a gamepad * will be sent on init *and* the order in which they will be @@ -117,8 +112,6 @@ typedef struct { SDL_bool initialized; Uint8 sequence; Uint8 last_state[USB_PACKET_LENGTH]; - SDL_bool rumble_synchronized; - SDL_bool rumble_synchronization_complete; SDL_bool has_paddles; } SDL_DriverXboxOne_Context; @@ -168,47 +161,6 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id) return SDL_FALSE; } -static SDL_bool -ControllerNeedsRumbleSequenceSynchronized(Uint16 vendor_id, Uint16 product_id) -{ - if (vendor_id == USB_VENDOR_MICROSOFT) { - /* All Xbox One controllers, from model 1537 through Elite Series 2, appear to need this */ - return SDL_TRUE; - } - return SDL_FALSE; -} - -static SDL_bool -SynchronizeRumbleSequence(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) -{ - Uint16 vendor_id = ctx->vendor_id; - Uint16 product_id = ctx->product_id; - - if (ctx->rumble_synchronized) { - return SDL_TRUE; - } - - if (ControllerNeedsRumbleSequenceSynchronized(vendor_id, product_id)) { - int i; - Uint8 init_packet[USB_PACKET_LENGTH]; - - SDL_memcpy(init_packet, xboxone_rumble_reset, sizeof(xboxone_rumble_reset)); - for (i = 0; i < 255; ++i) { - init_packet[2] = ((ctx->sequence + i) % 255); - if (SDL_HIDAPI_LockRumble() < 0) { - return SDL_FALSE; - } - if (SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, sizeof(xboxone_rumble_reset)) != sizeof(xboxone_rumble_reset)) { - SDL_SetError("Couldn't write Xbox One initialization packet"); - return SDL_FALSE; - } - } - } - ctx->rumble_synchronized = SDL_TRUE; - - return SDL_TRUE; -} - /* Return true if this controller sends the 0x02 "waiting for init" packet */ static SDL_bool ControllerSendsWaitingForInit(Uint16 vendor_id, Uint16 product_id) @@ -293,8 +245,6 @@ SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) } } - SynchronizeRumbleSequence(device, ctx); - return SDL_TRUE; } @@ -373,41 +323,14 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst static int HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { - SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF }; - Uint8 *pending_rumble; - int *pending_size; - int maximum_size; - SynchronizeRumbleSequence(device, ctx); + /* Magnitude is 1..100 so scale the 16-bit input here */ + rumble_packet[8] = low_frequency_rumble / 655; + rumble_packet[9] = high_frequency_rumble / 655; - if (SDL_HIDAPI_LockRumble() < 0) { - return -1; - } - - if (!ctx->rumble_synchronization_complete) { - if (!SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_rumble, &pending_size, &maximum_size)) { - /* Rumble synchronization has drained */ - ctx->rumble_synchronization_complete = SDL_TRUE; - } - } - - /* Try to overwrite any pending rumble with the new value */ - if (ctx->rumble_synchronization_complete && - SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_rumble, &pending_size, &maximum_size)) { - /* Magnitude is 1..100 so scale the 16-bit input here */ - pending_rumble[8] = low_frequency_rumble / 655; - pending_rumble[9] = high_frequency_rumble / 655; - SDL_HIDAPI_UnlockRumble(); - } else { - /* Magnitude is 1..100 so scale the 16-bit input here */ - rumble_packet[2] = ctx->sequence++; - rumble_packet[8] = low_frequency_rumble / 655; - rumble_packet[9] = high_frequency_rumble / 655; - - if (SDL_HIDAPI_SendRumbleAndUnlock(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { - return SDL_SetError("Couldn't send rumble packet"); - } + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); } return 0; }