mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-03-20 15:51:07 +01:00
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
This commit is contained in:
@@ -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 <windows.h>
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user