From 883066228b9d0f745aad8958099897fc686670b7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Feb 2026 20:34:49 -0800 Subject: [PATCH] Minor code cleanup - the connection type is already set correctly based on bluetooth connection state - removed some verbose controller type logging - device and ctx are guaranteed not to be NULL at the driver level --- src/joystick/hidapi/SDL_hidapi_gamesir.c | 518 +++++++++-------------- 1 file changed, 201 insertions(+), 317 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_gamesir.c b/src/joystick/hidapi/SDL_hidapi_gamesir.c index 8c357253f7..728a845f4c 100644 --- a/src/joystick/hidapi/SDL_hidapi_gamesir.c +++ b/src/joystick/hidapi/SDL_hidapi_gamesir.c @@ -26,6 +26,162 @@ #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" +#ifdef SDL_JOYSTICK_HIDAPI_GAMESIR + +// Define this if you want to log all packets from the controller +#if 0 +#define DEBUG_GAMESIR_PROTOCOL +#endif + +#define GAMESIR_PACKET_HEADER_0 0xA1 +#define GAMESIR_PACKET_HEADER_1_GAMEPAD 0xC8 + +#define BTN_A 0x01 +#define BTN_B 0x02 +#define BTN_C 0x04 +#define BTN_X 0x08 +#define BTN_Y 0x10 +#define BTN_Z 0x20 +#define BTN_L1 0x40 +#define BTN_R1 0x80 + +#define BTN_L2 0x01 +#define BTN_R2 0x02 +#define BTN_SELECT 0x04 +#define BTN_START 0x08 +#define BTN_HOME 0x10 +#define BTN_L3 0x20 +#define BTN_R3 0x40 +#define BTN_CAPTURE 0x80 + +#define BTN_UP 0x01 +#define BTN_UP_L 0x08 +#define BTN_UP_R 0x02 +#define BTN_DOWN 0x05 +#define BTN_DOWN_L 0x06 +#define BTN_DOWN_R 0X04 +#define BTN_LEFT 0x07 +#define BTN_RIGHT 0x03 + +#define BTN_M 0x10 +#define BTN_MUTE 0x20 +#define BTN_L4 0x40 +#define BTN_R4 0x80 + +#define BTN_L5 0x01 +#define BTN_R5 0x02 +#define BTN_L6 0x04 +#define BTN_R6 0x08 +#define BTN_L7 0x10 +#define BTN_R7 0x20 +#define BTN_L8 0x40 +#define BTN_R8 0x80 + +typedef struct { + Uint8 cmd; + Uint8 mode; +} Gamesir_CommandMode; + +typedef struct { + bool sensors_supported; + bool sensors_enabled; + bool led_supported; + Uint64 sensor_timestamp_ns; + Uint64 sensor_timestamp_step_ns; + float accelScale; + float gyroScale; + bool last_state_initialized; + Uint8 last_state[USB_PACKET_LENGTH]; + SDL_hid_device *output_handle; +} SDL_DriverGamesir_Context; + + +static void HIDAPI_DriverGameSir_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, callback, userdata); +} + + +static void HIDAPI_DriverGameSir_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, callback, userdata); +} + + +static bool HIDAPI_DriverGameSir_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + + +static bool HIDAPI_DriverGameSir_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return SDL_IsJoystickGameSirController(vendor_id, product_id); +} + +static SDL_hid_device *HIDAPI_DriverGameSir_GetOutputHandle(SDL_HIDAPI_Device *device) +{ +#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) + SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; + return ctx->output_handle; +#else + return device->dev; +#endif +} + +static SDL_hid_device *HIDAPI_DriverGameSir_GetInputHandle(SDL_HIDAPI_Device *device, SDL_DriverGamesir_Context *ctx) +{ +#if defined(_WIN32) + if (device->is_bluetooth) { + return device->dev; + } + if (ctx->output_handle) { + return ctx->output_handle; + } + return device->dev; +#else + return device->dev; +#endif +} + +static bool SendGameSirModeSwitch(SDL_HIDAPI_Device *device) +{ + Gamesir_CommandMode cmd = { 0x01, 0x00 }; + Uint8 buf[64]; + SDL_zero(buf); + buf[0] = 0xA2; + SDL_memcpy(buf + 1, &cmd, sizeof(cmd)); + + SDL_hid_device *handle = HIDAPI_DriverGameSir_GetOutputHandle(device); + if (handle == NULL) { + return false; + } + + for (int attempt = 0; attempt < 3; ++attempt) { + int result = SDL_hid_write(handle, buf, sizeof(buf)); + if (result < 0) { + return false; + } + for (int i = 0; i < 10; ++i) { + SDL_Delay(1); + + Uint8 data[USB_PACKET_LENGTH] = {0}; + int size = SDL_hid_read_timeout(handle, data, sizeof(data), 0); + if (size < 0) { + break; + } + if (size == 0) { + continue; + } + + if (size == 64 && data[0] == 0xA1 && data[1] == 0x43 && data[2] == 0x01) { + return true; + } + } + } + return false; +} + /* ========================================================================= */ /* Win32 HID helper */ /* ========================================================================= */ @@ -34,12 +190,6 @@ * These APIs are NOT available on GDK platforms. */ #if defined(SDL_PLATFORM_WIN32) && !defined(SDL_PLATFORM_GDK) -#define SDL_HAS_WIN32_HID 1 -#else -#define SDL_HAS_WIN32_HID 0 -#endif - -#if SDL_HAS_WIN32_HID /* --- Win32 HID includes ------------------------------------------------- */ #include @@ -158,236 +308,48 @@ static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index) return NULL; } -#else /* !SDL_HAS_WIN32_HID */ -/* Stub for GDK / non-Win32 platforms */ +#endif // SDL_PLATFORM_WIN32 && !SDL_PLATFORM_GDK -#if defined(__GNUC__) || defined(__clang__) -#define SDL_UNUSED_FUNC __attribute__((unused)) -#else -#define SDL_UNUSED_FUNC -#endif - -static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index) SDL_UNUSED_FUNC; -static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index) -{ - (void)vid; - (void)pid; - (void)collection_index; - return NULL; -} - -#endif /* SDL_HAS_WIN32_HID */ - -#ifdef SDL_JOYSTICK_HIDAPI_GAMESIR - -#define GAMESIR_PACKET_HEADER_0 0xA1 -#define GAMESIR_PACKET_HEADER_1_GAMEPAD 0xC8 - -#define BTN_A 0x01 -#define BTN_B 0x02 -#define BTN_C 0x04 -#define BTN_X 0x08 -#define BTN_Y 0x10 -#define BTN_Z 0x20 -#define BTN_L1 0x40 -#define BTN_R1 0x80 - -#define BTN_L2 0x01 -#define BTN_R2 0x02 -#define BTN_SELECT 0x04 -#define BTN_START 0x08 -#define BTN_HOME 0x10 -#define BTN_L3 0x20 -#define BTN_R3 0x40 -#define BTN_CAPTURE 0x80 - -#define BTN_UP 0x01 -#define BTN_UP_L 0x08 -#define BTN_UP_R 0x02 -#define BTN_DOWN 0x05 -#define BTN_DOWN_L 0x06 -#define BTN_DOWN_R 0X04 -#define BTN_LEFT 0x07 -#define BTN_RIGHT 0x03 - -#define BTN_M 0x10 -#define BTN_MUTE 0x20 -#define BTN_L4 0x40 -#define BTN_R4 0x80 - -#define BTN_L5 0x01 -#define BTN_R5 0x02 -#define BTN_L6 0x04 -#define BTN_R6 0x08 -#define BTN_L7 0x10 -#define BTN_R7 0x20 -#define BTN_L8 0x40 -#define BTN_R8 0x80 - -#ifndef DEG2RAD -#define DEG2RAD(x) ((float)(x) * (float)(SDL_PI_F / 180.f)) -#endif - -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) - -typedef struct { - Uint8 cmd; - Uint8 mode; -} Gamesir_CommandMode; - -typedef struct { - bool sensors_supported; - bool sensors_enabled; - bool led_supported; - Uint64 sensor_timestamp_ns; - Uint64 sensor_timestamp_step_ns; - float accelScale; - float gyroScale; - bool last_state_initialized; - Uint8 last_state[USB_PACKET_LENGTH]; - SDL_hid_device *output_handle; -} SDL_DriverGamesir_Context; - - -static void HIDAPI_DriverGameSir_RegisterHints(SDL_HintCallback callback, void *userdata) -{ - SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, callback, userdata); -} - - -static void HIDAPI_DriverGameSir_UnregisterHints(SDL_HintCallback callback, void *userdata) -{ - SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, callback, userdata); -} - - -static bool HIDAPI_DriverGameSir_IsEnabled(void) -{ - return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_GAMESIR, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); -} - - -static bool HIDAPI_DriverGameSir_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GamepadType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) -{ - return SDL_IsJoystickGameSirController(vendor_id, product_id); -} - -static SDL_hid_device *HIDAPI_DriverGameSir_GetOutputHandle(SDL_HIDAPI_Device *device) -{ -#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) - SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (ctx && ctx->output_handle) { - return ctx->output_handle; - } - return NULL; -#else - return device->dev; -#endif -} - -static SDL_hid_device *HIDAPI_DriverGameSir_GetInputHandle(SDL_HIDAPI_Device *device, SDL_DriverGamesir_Context *ctx) -{ -#if defined(_WIN32) - if (device->is_bluetooth) { - return device->dev; - } - if (ctx && ctx->output_handle) { - return ctx->output_handle; - } - return device->dev; -#else - return device->dev; -#endif -} - - -static bool SendGameSirModeSwitch(SDL_HIDAPI_Device *device) -{ - Gamesir_CommandMode cmd = { 0x01, 0x00 }; - Uint8 buf[64]; - SDL_zero(buf); - buf[0] = 0xA2; - SDL_memcpy(buf + 1, &cmd, sizeof(cmd)); - - SDL_hid_device *handle = HIDAPI_DriverGameSir_GetOutputHandle(device); - SDL_assert(handle != NULL); - if (handle == NULL) { - return false; - } - for (int attempt = 0; attempt < 3; ++attempt) { - int result = SDL_hid_write(handle, buf, sizeof(buf)); - if (result < 0) { - return false; - } - for (int i = 0; i < 10; ++i) { - SDL_Delay(1); - - Uint8 data[USB_PACKET_LENGTH] = {0}; - int size = SDL_hid_read_timeout(handle, data, sizeof(data), 0); - if (size < 0) { - break; - } - if (size == 0) { - continue; - } - - if (size == 64 && data[0] == 0xA1 && data[1] == 0x43 && data[2] == 0x01) { - return true; - } - } - } - - SDL_Delay(10); - return true; -} - -static bool HIDAPI_DriverGameSir_InitDevice(SDL_HIDAPI_Device *device) +static SDL_hid_device *GetOutputHandle(SDL_HIDAPI_Device *device) { Uint16 vendor_id = device->vendor_id; Uint16 product_id = device->product_id; SDL_hid_device *output_handle = NULL; - struct SDL_hid_device_info *devs = SDL_hid_enumerate(vendor_id, product_id); - for (struct SDL_hid_device_info *info = devs; info; info = info->next) { + for (struct SDL_hid_device_info *info = devs; info && !output_handle; info = info->next) { if (info->interface_number == 0) { -#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK) - if (!output_handle) { - char *col02_path = FindHIDInterfacePath(vendor_id, product_id, 2); - if (col02_path) { - output_handle = SDL_hid_open_path(col02_path); - SDL_free(col02_path); - } +#if defined(SDL_PLATFORM_WIN32) && !defined(SDL_PLATFORM_GDK) + char *col02_path = FindHIDInterfacePath(vendor_id, product_id, 2); + if (col02_path) { + output_handle = SDL_hid_open_path(col02_path); + SDL_free(col02_path); } #endif - } - if (info->interface_number == -1) { + } else if (info->interface_number == -1) { #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) if (info->usage_page == 0x0001 && info->usage == 0x0005) { output_handle = SDL_hid_open_path(info->path); - if (output_handle) { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Opened output interface via path pattern"); - break; - } } #endif - } else if (!output_handle && info->interface_number == 1) { + } else if (info->interface_number == 1) { output_handle = SDL_hid_open_path(info->path); } } SDL_hid_free_enumeration(devs); + return output_handle; +} + +static bool HIDAPI_DriverGameSir_InitDevice(SDL_HIDAPI_Device *device) +{ SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { - SDL_hid_close(device->dev); - if (output_handle) { - SDL_hid_close(output_handle); - } return false; } + device->context = ctx; ctx->led_supported = true; - ctx->output_handle = output_handle; - device->context = ctx; + ctx->output_handle = GetOutputHandle(device); switch (device->product_id) { case USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_HID: @@ -438,30 +400,6 @@ static bool HIDAPI_DriverGameSir_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy SendGameSirModeSwitch(device); - if (device->product_id == USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_HID) { - if (device->is_bluetooth) { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: Bluetooth (wireless, HID mode)"); - } else { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRED; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: USB/2.4G (HID mode)"); - } - } else if (device->product_id == USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_8K_HID) { - if (device->is_bluetooth) { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: Bluetooth (wireless, 8K HID mode)"); - } else { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRED; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: USB/2.4G (8K HID mode)"); - } - } else if (device->is_bluetooth) { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRELESS; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: Bluetooth (wireless)"); - } else { - joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRED; - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Joystick opened - Connection type: USB (wired)"); - } - joystick->nbuttons = 35; joystick->naxes = SDL_GAMEPAD_AXIS_COUNT; joystick->nhats = 1; @@ -491,13 +429,6 @@ static bool HIDAPI_DriverGameSir_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy static bool HIDAPI_DriverGameSir_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { - if (!device) { - return false; - } - SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (!ctx) { - return false; - } Uint8 buf[64]; SDL_zero(buf); buf[0] = 0xA2; @@ -506,7 +437,6 @@ static bool HIDAPI_DriverGameSir_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_J buf[3] = (Uint8)(high_frequency_rumble / 256); SDL_hid_device *handle = HIDAPI_DriverGameSir_GetOutputHandle(device); - SDL_assert(handle != NULL); if (handle == NULL) { return false; } @@ -515,20 +445,13 @@ static bool HIDAPI_DriverGameSir_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_J if (result < 0) { return false; } - return true; } static bool HIDAPI_DriverGameSir_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { - if (!device) { - return false; - } - SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (!ctx) { - return false; - } + // FIXME: This is the same report as rumble above, is this intentional? Uint8 buf[64]; SDL_zero(buf); buf[0] = 0xA2; @@ -537,7 +460,6 @@ static bool HIDAPI_DriverGameSir_RumbleJoystickTriggers(SDL_HIDAPI_Device *devic buf[5] = (Uint8)(right_rumble / 256); SDL_hid_device *handle = HIDAPI_DriverGameSir_GetOutputHandle(device); - SDL_assert(handle != NULL); if (handle == NULL) { return false; } @@ -546,7 +468,6 @@ static bool HIDAPI_DriverGameSir_RumbleJoystickTriggers(SDL_HIDAPI_Device *devic if (result < 0) { return false; } - return true; } @@ -564,17 +485,12 @@ static Uint32 HIDAPI_DriverGameSir_GetJoystickCapabilities(SDL_HIDAPI_Device *de static bool HIDAPI_DriverGameSir_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { - if (!device) { - return false; - } - SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (!ctx) { - return false; - } + if (!ctx->led_supported) { return SDL_Unsupported(); } + Uint8 buf[64]; SDL_zero(buf); buf[0] = 0xA2; @@ -585,7 +501,6 @@ static bool HIDAPI_DriverGameSir_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_J buf[5] = green; buf[6] = blue; SDL_hid_device *handle = HIDAPI_DriverGameSir_GetOutputHandle(device); - SDL_assert(handle != NULL); if (handle == NULL) { return false; } @@ -594,7 +509,6 @@ static bool HIDAPI_DriverGameSir_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_J if (result < 0) { return false; } - return true; } @@ -606,7 +520,7 @@ static bool HIDAPI_DriverGameSir_SendJoystickEffect(SDL_HIDAPI_Device *device, S static bool HIDAPI_DriverGameSir_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled) { SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (ctx && ctx->sensors_supported) { + if (ctx->sensors_supported) { ctx->sensors_enabled = enabled; return true; } @@ -645,11 +559,6 @@ static void HIDAPI_DriverGameSir_HandleStatePacket(SDL_Joystick *joystick, SDL_D { Sint16 axis; Uint64 timestamp = SDL_GetTicksNS(); - - if (!joystick || !ctx || !data || size <= 0) { - return; - } - const Uint8 *last = ctx->last_state; bool is_initial_packet = !ctx->last_state_initialized; @@ -907,72 +816,47 @@ static void HIDAPI_DriverGameSir_HandleStatePacket(SDL_Joystick *joystick, SDL_D static bool HIDAPI_DriverGameSir_UpdateDevice(SDL_HIDAPI_Device *device) { - if (!device) { - return false; - } - SDL_DriverGamesir_Context *ctx = (SDL_DriverGamesir_Context *)device->context; - if (!ctx) { - return false; - } - SDL_Joystick *joystick = NULL; Uint8 data[USB_PACKET_LENGTH]; int size; if (device->num_joysticks > 0) { joystick = SDL_GetJoystickFromID(device->joysticks[0]); - if (!joystick) { - return false; - } } SDL_hid_device *handle = HIDAPI_DriverGameSir_GetInputHandle(device, ctx); - SDL_assert(handle != NULL); if (handle == NULL) { return false; } while ((size = SDL_hid_read_timeout(handle, data, sizeof(data), 0)) > 0) { - if (joystick) { - Uint8 *payload = NULL; - int payload_size = 0; +#ifdef DEBUG_GAMESIR_PROTOCOL + HIDAPI_DumpPacket("GameSir packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } - // Check packet format: it may include a report ID (0x43) as the first byte - // Actual packet format: 43 a1 c8 [button data...] - // If the first byte is 0x43, the second is 0xA1 and the third is 0xC8, skip the report ID - if (size >= 3 && data[0] == 0x43 && data[1] == GAMESIR_PACKET_HEADER_0 && data[2] == GAMESIR_PACKET_HEADER_1_GAMEPAD) { - payload = data + 3; - payload_size = size - 3; - } else if (size >= 2 && data[0] == GAMESIR_PACKET_HEADER_0 && data[1] == GAMESIR_PACKET_HEADER_1_GAMEPAD) { - payload = data + 2; - payload_size = size - 2; - } - - if (payload) { - HIDAPI_DriverGameSir_HandleStatePacket(joystick, ctx, payload, payload_size); - } + // Check packet format: it may include a report ID (0x43) as the first byte + // Actual packet format: 43 a1 c8 [button data...] + // If the first byte is 0x43, the second is 0xA1 and the third is 0xC8, skip the report ID + Uint8 *payload = NULL; + int payload_size = 0; + if (size >= 3 && data[0] == 0x43 && data[1] == GAMESIR_PACKET_HEADER_0 && data[2] == GAMESIR_PACKET_HEADER_1_GAMEPAD) { + payload = data + 3; + payload_size = size - 3; + } else if (size >= 2 && data[0] == GAMESIR_PACKET_HEADER_0 && data[1] == GAMESIR_PACKET_HEADER_1_GAMEPAD) { + payload = data + 2; + payload_size = size - 2; + } + if (payload) { + HIDAPI_DriverGameSir_HandleStatePacket(joystick, ctx, payload, payload_size); } } - if (size < 0) { - if (device->product_id == USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_HID) { - if (device->is_bluetooth) { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: Bluetooth (wireless, HID mode)"); - } else { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: USB/2.4G (HID mode)"); - } - } else if (device->product_id == USB_PRODUCT_GAMESIR_GAMEPAD_G7_PRO_8K_HID) { - if (device->is_bluetooth) { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: Bluetooth (wireless, 8K HID mode)"); - } else { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: USB/2.4G (8K HID mode)"); - } - } else if (device->is_bluetooth) { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: Bluetooth (wireless)"); - } else { - SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "GameSir: Device disconnected - Connection type was: USB (wired)"); - } + if (size < 0 && device->num_joysticks > 0) { + // Read error, device is disconnected HIDAPI_JoystickDisconnected(device, device->joysticks[0]); } return (size >= 0); @@ -1017,6 +901,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameSir = { HIDAPI_DriverGameSir_FreeDevice, }; -#endif +#endif // SDL_JOYSTICK_HIDAPI_GAMESIR -#endif +#endif // SDL_JOYSTICK_HIDAPI