From 4aeec9d8c2ad2fa0465999ecb4fd5c20734f1b27 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 21 Feb 2023 15:05:57 -0800 Subject: [PATCH] Rumbling the Google Stadia Controller over Bluetooth works on Linux and macOS --- src/joystick/hidapi/SDL_hidapi_stadia.c | 37 ++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_stadia.c b/src/joystick/hidapi/SDL_hidapi_stadia.c index 1b3b1861e..175080807 100644 --- a/src/joystick/hidapi/SDL_hidapi_stadia.c +++ b/src/joystick/hidapi/SDL_hidapi_stadia.c @@ -40,6 +40,7 @@ enum typedef struct { + SDL_bool rumble_supported; Uint8 last_state[USB_PACKET_LENGTH]; } SDL_DriverStadia_Context; @@ -74,12 +75,12 @@ static SDL_bool HIDAPI_DriverStadia_InitDevice(SDL_HIDAPI_Device *device) } device->context = ctx; - /* Check whether this is connected via USB or Bluetooth */ + /* Check whether rumble is supported */ { Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; - if (SDL_hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) < 0) { - device->is_bluetooth = SDL_TRUE; + if (SDL_hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) >= 0) { + ctx->rumble_supported = SDL_TRUE; } } @@ -116,21 +117,24 @@ static SDL_bool HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_ static int HIDAPI_DriverStadia_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { - Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; - if (device->is_bluetooth) { + if (ctx->rumble_supported) { + Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; + + + rumble_packet[1] = (low_frequency_rumble & 0xFF); + rumble_packet[2] = (low_frequency_rumble >> 8); + rumble_packet[3] = (high_frequency_rumble & 0xFF); + rumble_packet[4] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; + } else { return SDL_Unsupported(); } - - rumble_packet[1] = (low_frequency_rumble & 0xFF); - rumble_packet[2] = (low_frequency_rumble >> 8); - rumble_packet[3] = (high_frequency_rumble & 0xFF); - rumble_packet[4] = (high_frequency_rumble >> 8); - - if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { - return SDL_SetError("Couldn't send rumble packet"); - } - return 0; } static int HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) @@ -140,9 +144,10 @@ static int HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, static Uint32 HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) { + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; Uint32 caps = 0; - if (!device->is_bluetooth) { + if (ctx->rumble_supported) { caps |= SDL_JOYCAP_RUMBLE; } return caps;