Don't send k_ePS4FeatureReportIdCapabilities to Sony PS4 controllers

This report is for third party controllers only, and might be causing issues with fake PS4 controllers.

Reference https://github.com/libsdl-org/SDL/issues/7960

(cherry picked from commit 092a4b780ca464de71b89ffa5dc655ce256ce350)
This commit is contained in:
Sam Lantinga 2023-07-10 09:15:02 -07:00
parent 92fd2938e7
commit 6bf5f5a221

View File

@ -320,81 +320,83 @@ static SDL_bool HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
SDL_Log("PS4 dongle = %s, bluetooth = %s\n", ctx->is_dongle ? "TRUE" : "FALSE", device->is_bluetooth ? "TRUE" : "FALSE");
#endif
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data));
/* Get the device capabilities */
if (size == 48 && data[2] == 0x27) {
Uint8 capabilities = data[4];
Uint8 device_type = data[5];
Uint16 gyro_numerator = LOAD16(data[10], data[11]);
Uint16 gyro_denominator = LOAD16(data[12], data[13]);
Uint16 accel_numerator = LOAD16(data[14], data[15]);
Uint16 accel_denominator = LOAD16(data[16], data[17]);
#ifdef DEBUG_PS4_PROTOCOL
HIDAPI_DumpPacket("PS4 capabilities: size = %d", data, size);
#endif
if (capabilities & 0x02) {
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x04:
joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
if (gyro_numerator && gyro_denominator) {
ctx->gyro_numerator = gyro_numerator;
ctx->gyro_denominator = gyro_denominator;
}
if (accel_numerator && accel_denominator) {
ctx->accel_numerator = accel_numerator;
ctx->accel_denominator = accel_denominator;
}
} else if (device->vendor_id == USB_VENDOR_SONY) {
if (device->vendor_id == USB_VENDOR_SONY) {
ctx->official_controller = SDL_TRUE;
ctx->sensors_supported = SDL_TRUE;
ctx->lightbar_supported = SDL_TRUE;
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
} else if (device->vendor_id == USB_VENDOR_RAZER) {
/* The Razer Raiju doesn't respond to the detection protocol, but has a touchpad and vibration */
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
} else {
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data));
/* Get the device capabilities */
if (size == 48 && data[2] == 0x27) {
Uint8 capabilities = data[4];
Uint8 device_type = data[5];
Uint16 gyro_numerator = LOAD16(data[10], data[11]);
Uint16 gyro_denominator = LOAD16(data[12], data[13]);
Uint16 accel_numerator = LOAD16(data[14], data[15]);
Uint16 accel_denominator = LOAD16(data[16], data[17]);
if (device->product_id == USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH ||
device->product_id == USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH) {
device->is_bluetooth = SDL_TRUE;
#ifdef DEBUG_PS4_PROTOCOL
HIDAPI_DumpPacket("PS4 capabilities: size = %d", data, size);
#endif
if (capabilities & 0x02) {
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x04:
joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
if (gyro_numerator && gyro_denominator) {
ctx->gyro_numerator = gyro_numerator;
ctx->gyro_denominator = gyro_denominator;
}
if (accel_numerator && accel_denominator) {
ctx->accel_numerator = accel_numerator;
ctx->accel_denominator = accel_denominator;
}
} else if (device->vendor_id == USB_VENDOR_RAZER) {
/* The Razer Raiju doesn't respond to the detection protocol, but has a touchpad and vibration */
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
if (device->product_id == USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH ||
device->product_id == USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH) {
device->is_bluetooth = SDL_TRUE;
}
}
}
ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported);