From 5b8fc907df5866cc7e30c523c6ea499eb6f8a4d4 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 17 Jun 2023 12:42:55 -0700
Subject: [PATCH] Added support for the GameSir G4 Pro
We can't read device info or IMU calibration from this controller, and it has no gyro or accelerometer, but is otherwise perfectly functional.
(cherry picked from commit f168f9c81326ad374aade49d1dc46f245b20d07a)
---
src/joystick/hidapi/SDL_hidapi_switch.c | 99 +++++++++++--------------
1 file changed, 45 insertions(+), 54 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 8b9d5e82ae0b..4a117199c320 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -592,35 +592,30 @@ static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx)
{
SwitchSubcommandInputPacket_t *reply = NULL;
- ctx->device->is_bluetooth = SDL_FALSE;
-
- if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) {
- SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0];
- size_t i;
+ if (ctx->device->is_bluetooth) {
+ if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) {
+ // Byte 2: Controller ID (1=LJC, 2=RJC, 3=Pro)
+ ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType);
- ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType);
+ // Bytes 4-9: MAC address (big-endian)
+ SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
- for (i = 0; i < sizeof(ctx->m_rgucMACAddress); ++i) {
- ctx->m_rgucMACAddress[i] = status->rgucMACAddress[sizeof(ctx->m_rgucMACAddress) - i - 1];
+ return SDL_TRUE;
}
+ } else {
+ if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) {
+ SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0];
+ size_t i;
- return SDL_TRUE;
- }
-
- ctx->device->is_bluetooth = SDL_TRUE;
-
- if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) {
- // Byte 2: Controller ID (1=LJC, 2=RJC, 3=Pro)
- ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType);
+ ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType);
- // Bytes 4-9: MAC address (big-endian)
- SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
+ for (i = 0; i < sizeof(ctx->m_rgucMACAddress); ++i) {
+ ctx->m_rgucMACAddress[i] = status->rgucMACAddress[sizeof(ctx->m_rgucMACAddress) - i - 1];
+ }
- return SDL_TRUE;
+ return SDL_TRUE;
+ }
}
-
- ctx->device->is_bluetooth = SDL_FALSE;
-
return SDL_FALSE;
}
@@ -1042,7 +1037,8 @@ static SDL_bool HasHomeLED(SDL_DriverSwitch_Context *ctx)
}
/* Third party controllers don't have a home LED and will shut off if we try to set it */
- if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_LicProController) {
+ if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_Unknown ||
+ ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_LicProController) {
return SDL_FALSE;
}
@@ -1243,6 +1239,9 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER);
device->type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
+ case k_eSwitchDeviceInfoControllerType_Unknown:
+ /* We couldn't read the device info for this controller, might not be fully compliant */
+ return;
default:
break;
}
@@ -1285,12 +1284,7 @@ static SDL_bool HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]);
SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]);
- if (!BReadDeviceInfo(ctx)) {
- SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
- "HIDAPI_DriverSwitch_InitDevice(): Couldn't read device info");
- return SDL_FALSE;
- }
-
+ BReadDeviceInfo(ctx);
UpdateDeviceIdentity(device);
}
@@ -1345,39 +1339,36 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
}
}
+ if (!LoadStickCalibration(ctx)) {
+ SDL_SetError("Couldn't load stick calibration");
+ return SDL_FALSE;
+ }
+
if (ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESRight &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SNES &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_N64 &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SEGA_Genesis) {
- /* Use the right sensor in the combined Joy-Con pair */
- if (!device->parent ||
- ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f);
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f);
- }
- if (device->parent &&
- ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_L, 200.0f);
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 200.0f);
- }
- if (device->parent &&
- ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_R, 200.0f);
- SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_R, 200.0f);
+ if (LoadIMUCalibration(ctx)) {
+ /* Use the right sensor in the combined Joy-Con pair */
+ if (!device->parent ||
+ ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f);
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f);
+ }
+ if (device->parent &&
+ ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) {
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_L, 200.0f);
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 200.0f);
+ }
+ if (device->parent &&
+ ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_R, 200.0f);
+ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_R, 200.0f);
+ }
}
}
- if (!LoadStickCalibration(ctx)) {
- SDL_SetError("Couldn't load stick calibration");
- return SDL_FALSE;
- }
-
- if (!LoadIMUCalibration(ctx)) {
- SDL_SetError("Couldn't load sensor calibration");
- return SDL_FALSE;
- }
-
if (!SetVibrationEnabled(ctx, 1)) {
SDL_SetError("Couldn't enable vibration");
return SDL_FALSE;