From 883066228b9d0f745aad8958099897fc686670b7 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 | 474 +++++++++--------------
1 file changed, 179 insertions(+), 295 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_gamesir.c b/src/joystick/hidapi/SDL_hidapi_gamesir.c
index 8c357253f76d4..728a845f4ca0a 100644
--- a/src/joystick/hidapi/SDL_hidapi_gamesir.c
+++ b/src/joystick/hidapi/SDL_hidapi_gamesir.c
@@ -26,160 +26,13 @@
#include "SDL_hidapijoystick_c.h"
#include "SDL_hidapi_rumble.h"
-/* ========================================================================= */
-/* Win32 HID helper */
-/* ========================================================================= */
-
-/* This helper requires full desktop Win32 HID APIs.
- * 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 <windows.h>
-#include <setupapi.h>
-#include <hidsdi.h>
-
-#if defined(_MSC_VER)
-#pragma comment(lib, "setupapi.lib")
-#pragma comment(lib, "hid.lib")
-#endif
-
-static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index)
-{
- GUID hidGuid;
- HidD_GetHidGuid(&hidGuid);
-
- HDEVINFO deviceInfoSet = SetupDiGetClassDevs(
- &hidGuid, NULL, NULL,
- DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
- );
- if (deviceInfoSet == INVALID_HANDLE_VALUE) {
- return NULL;
- }
-
- SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
- deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
-
- for (DWORD i = 0;
- SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &hidGuid, i, &deviceInterfaceData);
- i++) {
-
- DWORD requiredSize = 0;
- SetupDiGetDeviceInterfaceDetail(
- deviceInfoSet, &deviceInterfaceData,
- NULL, 0, &requiredSize, NULL
- );
-
- PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail =
- (PSP_DEVICE_INTERFACE_DETAIL_DATA)SDL_malloc(requiredSize);
- if (!deviceDetail) {
- continue;
- }
-
- deviceDetail->cbSize = sizeof(*deviceDetail);
-
- if (!SetupDiGetDeviceInterfaceDetail(
- deviceInfoSet, &deviceInterfaceData,
- deviceDetail, requiredSize, NULL, NULL)) {
- SDL_free(deviceDetail);
- continue;
- }
-
- HANDLE hDevice = CreateFile(
- deviceDetail->DevicePath,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL
- );
-
- if (hDevice == INVALID_HANDLE_VALUE) {
- SDL_free(deviceDetail);
- continue;
- }
-
- HIDD_ATTRIBUTES attributes;
- attributes.Size = sizeof(attributes);
-
- if (!HidD_GetAttributes(hDevice, &attributes) ||
- attributes.VendorID != vid ||
- attributes.ProductID != pid) {
- CloseHandle(hDevice);
- SDL_free(deviceDetail);
- continue;
- }
-
- PHIDP_PREPARSED_DATA preparsedData = NULL;
- if (!HidD_GetPreparsedData(hDevice, &preparsedData) || !preparsedData) {
- CloseHandle(hDevice);
- SDL_free(deviceDetail);
- continue;
- }
-
- HIDP_CAPS caps;
- if (HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) {
- HidD_FreePreparsedData(preparsedData);
- CloseHandle(hDevice);
- SDL_free(deviceDetail);
- continue;
- }
-
- if ((caps.InputReportByteLength == 64 && caps.OutputReportByteLength == 64) ||
- (caps.InputReportByteLength == 37 && caps.OutputReportByteLength == 37)) {
-
- char col_str[16];
- SDL_snprintf(col_str, sizeof(col_str), "col%02d", collection_index);
-
- if (SDL_strcasestr(deviceDetail->DevicePath, col_str)) {
- char *result = SDL_strdup(deviceDetail->DevicePath);
- HidD_FreePreparsedData(preparsedData);
- CloseHandle(hDevice);
- SDL_free(deviceDetail);
- SetupDiDestroyDeviceInfoList(deviceInfoSet);
- return result;
- }
- }
-
- HidD_FreePreparsedData(preparsedData);
- CloseHandle(hDevice);
- SDL_free(deviceDetail);
- }
-
- SetupDiDestroyDeviceInfoList(deviceInfoSet);
- return NULL;
-}
-
-#else /* !SDL_HAS_WIN32_HID */
-/* Stub for GDK / non-Win32 platforms */
+#ifdef SDL_JOYSTICK_HIDAPI_GAMESIR
-#if defined(__GNUC__) || defined(__clang__)
-#define SDL_UNUSED_FUNC __attribute__((unused))
-#else
-#define SDL_UNUSED_FUNC
+// Define this if you want to log all packets from the controller
+#if 0
+#define DEBUG_GAMESIR_PROTOCOL
#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
@@ -224,12 +77,6 @@ static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index)
#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;
@@ -276,10 +123,7 @@ static SDL_hid_device *HIDAPI_DriverGameSir_GetOutputHandle(SDL_HIDAPI_Device *d
{
#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;
+ return ctx->output_handle;
#else
return device->dev;
#endif
@@ -291,7 +135,7 @@ static SDL_hid_device *HIDAPI_DriverGameSir_GetInputHandle(SDL_HIDAPI_Device *de
if (device->is_bluetooth) {
return device->dev;
}
- if (ctx && ctx->output_handle) {
+ if (ctx->output_handle) {
return ctx->output_handle;
}
return device->dev;
@@ -300,7 +144,6 @@ static SDL_hid_device *HIDAPI_DriverGameSir_GetInputHandle(SDL_HIDAPI_Device *de
#endif
}
-
static bool SendGameSirModeSwitch(SDL_HIDAPI_Device *device)
{
Gamesir_CommandMode cmd = { 0x01, 0x00 };
@@ -310,10 +153,10 @@ static bool SendGameSirModeSwitch(SDL_HIDAPI_Device *device)
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) {
@@ -336,58 +179,177 @@ static bool SendGameSirModeSwitch(SDL_HIDAPI_Device *device)
}
}
}
+ return false;
+}
- SDL_Delay(10);
- return true;
+/* ========================================================================= */
+/* Win32 HID helper */
+/* ========================================================================= */
+
+/* This helper requires full desktop Win32 HID APIs.
+ * These APIs are NOT available on GDK platforms.
+ */
+#if defined(SDL_PLATFORM_WIN32) && !defined(SDL_PLATFORM_GDK)
+
+/* --- Win32 HID includes ------------------------------------------------- */
+#include <windows.h>
+#include <setupapi.h>
+#include <hidsdi.h>
+
+#if defined(_MSC_VER)
+#pragma comment(lib, "setupapi.lib")
+#pragma comment(lib, "hid.lib")
+#endif
+
+static char *FindHIDInterfacePath(Uint16 vid, Uint16 pid, int collection_index)
+{
+ GUID hidGuid;
+ HidD_GetHidGuid(&hidGuid);
+
+ HDEVINFO deviceInfoSet = SetupDiGetClassDevs(
+ &hidGuid, NULL, NULL,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
+ );
+ if (deviceInfoSet == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
+
+ for (DWORD i = 0;
+ SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &hidGuid, i, &deviceInterfaceData);
+ i++) {
+
+ DWORD requiredSize = 0;
+ SetupDiGetDeviceInterfaceDetail(
+ deviceInfoSet, &deviceInterfaceData,
+ NULL, 0, &requiredSize, NULL
+ );
+
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail =
+ (PSP_DEVICE_INTERFACE_DETAIL_DATA)SDL_malloc(requiredSize);
+ if (!deviceDetail) {
+ continue;
+ }
+
+ deviceDetail->cbSize = sizeof(*deviceDetail);
+
+ if (!SetupDiGetDeviceInterfaceDetail(
+ deviceInfoSet, &deviceInterfaceData,
+ deviceDetail, requiredSize, NULL, NULL)) {
+ SDL_free(deviceDetail);
+ continue;
+ }
+
+ HANDLE hDevice = CreateFile(
+ deviceDetail->DevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL
+ );
+
+ if (hDevice == INVALID_HANDLE_VALUE) {
+ SDL_free(deviceDetail);
+ continue;
+ }
+
+ HIDD_ATTRIBUTES attributes;
+ attributes.Size = sizeof(attributes);
+
+ if (!HidD_GetAttributes(hDevice, &attributes) ||
+ attributes.VendorID != vid ||
+ attributes.ProductID != pid) {
+ CloseHandle(hDevice);
+ SDL_free(deviceDetail);
+ continue;
+ }
+
+ PHIDP_PREPARSED_DATA preparsedData = NULL;
+ if (!HidD_GetPreparsedData(hDevice, &preparsedData) || !preparsedData) {
+ CloseHandle(hDevice);
+ SDL_free(deviceDetail);
+ continue;
+ }
+
+ HIDP_CAPS caps;
+ if (HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) {
+ HidD_FreePreparsedData(preparsedData);
+ CloseHandle(hDevice);
+ SDL_free(deviceDetail);
+ continue;
+ }
+
+ if ((caps.InputReportByteLength == 64 && caps.OutputReportByteLength == 64) ||
+ (caps.InputReportByteLength == 37 && caps.OutputReportByteLength == 37)) {
+
+ char col_str[16];
+ SDL_snprintf(col_str, sizeof(col_str), "col%02d", collection_index);
+
+ if (SDL_strcasestr(deviceDetail->DevicePath, col_str)) {
+ char *result = SDL_strdup(deviceDetail->DevicePath);
+ HidD_FreePreparsedData(preparsedData);
+ CloseHandle(hDevice);
+ SDL_free(deviceDetail);
+ SetupDiDestroyDeviceInfoList(deviceInfoSet);
+ return result;
+ }
+ }
+
+ HidD_FreePreparsedData(preparsedData);
+ CloseHandle(hDevice);
+ SDL_free(deviceDetail);
+ }
+
+ SetupDiDestroyDeviceInfoList(deviceInfoSet);
+ return NULL;
}
-static bool HIDAPI_DriverGameSir_InitDevice(SDL_HIDAPI_Device *device)
+#endif // SDL_PLATFORM_WIN32 && !SDL_PLATFORM_GDK
+
+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;
-
- // 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;
- }
+#ifdef DEBUG_GAMESIR_PROTOCOL
+ HIDAPI_DumpPacket("GameSir packet: size = %d", data, size);
+#endif
+ if (!joystick) {
+ continue;
+ }
- 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