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.
main
Sam Lantinga 2023-06-17 12:42:55 -07:00
parent b770644411
commit f168f9c813
1 changed files with 48 additions and 57 deletions

View File

@ -586,35 +586,30 @@ static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx)
{
SwitchSubcommandInputPacket_t *reply = NULL;
ctx->device->is_bluetooth = SDL_FALSE;
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);
if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) {
SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0];
size_t i;
// Bytes 4-9: MAC address (big-endian)
SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType);
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->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType);
for (i = 0; i < sizeof(ctx->m_rgucMACAddress); ++i) {
ctx->m_rgucMACAddress[i] = status->rgucMACAddress[sizeof(ctx->m_rgucMACAddress) - i - 1];
}
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);
// Bytes 4-9: MAC address (big-endian)
SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
return SDL_TRUE;
}
ctx->device->is_bluetooth = SDL_FALSE;
return SDL_FALSE;
}
@ -1039,7 +1034,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;
}
@ -1240,6 +1236,9 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER);
device->type = SDL_GAMEPAD_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;
}
@ -1282,12 +1281,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);
}
@ -1342,37 +1336,34 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
}
}
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 (!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 (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) {
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 (!SetVibrationEnabled(ctx, 1)) {