mirror of https://github.com/encounter/SDL.git
Don't rely on the device VID/PID to get the Nintendo controller type
The Nintendo Online Sega Genesis controller reports the SNES VID/PID over Bluetooth. This is a more robust way of handling future controllers as well, so let's go with this instead. Also use full reports over Bluetooth, and don't report gyro for Nintendo Online classic controllers.
This commit is contained in:
parent
b6aadb16b9
commit
57c3b2c950
|
@ -587,21 +587,25 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
|
||||||
(vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) {
|
(vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) {
|
||||||
/* GameCube driver has 12 buttons and 6 axes */
|
/* GameCube driver has 12 buttons and 6 axes */
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string));
|
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string));
|
||||||
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_N64_CONTROLLER) {
|
} else if (vendor == USB_VENDOR_NINTENDO && guid.data[15] != 0 && guid.data[15] != 3) {
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string));
|
|
||||||
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) {
|
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b10,righttrigger:a5,start:b6,misc1:b15,", sizeof(mapping_string));
|
|
||||||
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) {
|
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string));
|
|
||||||
} else if (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product) ||
|
|
||||||
SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product) ||
|
|
||||||
SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product)) {
|
|
||||||
switch (guid.data[15]) {
|
switch (guid.data[15]) {
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
/* NES Controller */
|
/* NES Controller */
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string));
|
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string));
|
||||||
break;
|
break;
|
||||||
|
case 11:
|
||||||
|
/* SNES Controller */
|
||||||
|
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string));
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
/* N64 Controller */
|
||||||
|
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string));
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
/* SEGA Genesis Controller */
|
||||||
|
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b10,righttrigger:a5,start:b6,misc1:b15,", sizeof(mapping_string));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* Mini gamepad mode */
|
/* Mini gamepad mode */
|
||||||
SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,", sizeof(mapping_string));
|
SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,", sizeof(mapping_string));
|
||||||
|
|
|
@ -1095,36 +1095,55 @@ ReadJoyConControllerType(SDL_HIDAPI_Device *device)
|
||||||
return eControllerType;
|
return eControllerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
UpdateDeviceName(SDL_HIDAPI_Device *device, ESwitchDeviceInfoControllerType eControllerType)
|
||||||
|
{
|
||||||
|
const char *name = NULL;
|
||||||
|
|
||||||
|
switch (eControllerType) {
|
||||||
|
case k_eSwitchDeviceInfoControllerType_JoyConLeft:
|
||||||
|
name = "Nintendo Switch Joy-Con (L)";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_JoyConRight:
|
||||||
|
name = "Nintendo Switch Joy-Con (R)";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_ProController:
|
||||||
|
name = "Nintendo Switch Pro Controller";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_NESLeft:
|
||||||
|
name = "Nintendo NES Controller (L)";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_NESRight:
|
||||||
|
name = "Nintendo NES Controller (R)";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_SNES:
|
||||||
|
name = "Nintendo SNES Controller";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_N64:
|
||||||
|
name = "Nintendo N64 Controller";
|
||||||
|
break;
|
||||||
|
case k_eSwitchDeviceInfoControllerType_SEGA_Genesis:
|
||||||
|
name = "Nintendo SEGA Genesis Controller";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name && (!name || SDL_strcmp(name, device->name) != 0)) {
|
||||||
|
SDL_free(device->name);
|
||||||
|
device->name = SDL_strdup(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
|
HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
|
||||||
{
|
{
|
||||||
/* The NES controllers need additional fix up, since we can't detect them without opening the device */
|
/* The NES controllers need additional fix up, since we can't detect them without opening the device */
|
||||||
if (device->vendor_id == USB_VENDOR_NINTENDO &&
|
if (device->vendor_id == USB_VENDOR_NINTENDO) {
|
||||||
(device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT ||
|
|
||||||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP)) {
|
|
||||||
ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device);
|
ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device);
|
||||||
switch (eControllerType) {
|
switch (eControllerType) {
|
||||||
case k_eSwitchDeviceInfoControllerType_JoyConLeft:
|
|
||||||
SDL_free(device->name);
|
|
||||||
device->name = SDL_strdup("Nintendo Switch Joy-Con (L)");
|
|
||||||
device->guid.data[15] = eControllerType;
|
|
||||||
break;
|
|
||||||
case k_eSwitchDeviceInfoControllerType_JoyConRight:
|
|
||||||
SDL_free(device->name);
|
|
||||||
device->name = SDL_strdup("Nintendo Switch Joy-Con (R)");
|
|
||||||
device->guid.data[15] = eControllerType;
|
|
||||||
break;
|
|
||||||
case k_eSwitchDeviceInfoControllerType_NESLeft:
|
|
||||||
SDL_free(device->name);
|
|
||||||
device->name = SDL_strdup("NES Controller (L)");
|
|
||||||
device->guid.data[15] = eControllerType;
|
|
||||||
break;
|
|
||||||
case k_eSwitchDeviceInfoControllerType_NESRight:
|
|
||||||
SDL_free(device->name);
|
|
||||||
device->name = SDL_strdup("NES Controller (R)");
|
|
||||||
device->guid.data[15] = eControllerType;
|
|
||||||
break;
|
|
||||||
case k_eSwitchDeviceInfoControllerType_Unknown:
|
case k_eSwitchDeviceInfoControllerType_Unknown:
|
||||||
|
/* This might be a Joy-Con that's missing from a charging grip slot */
|
||||||
if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
|
if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
|
||||||
if (device->interface_number == 1) {
|
if (device->interface_number == 1) {
|
||||||
SDL_free(device->name);
|
SDL_free(device->name);
|
||||||
|
@ -1138,6 +1157,8 @@ HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
UpdateDeviceName(device, eControllerType);
|
||||||
|
device->guid.data[15] = eControllerType;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1208,17 +1229,16 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||||
* HandleFullControllerState is completely pointless. We need full state if we want battery
|
* HandleFullControllerState is completely pointless. We need full state if we want battery
|
||||||
* level and we only care about battery level over bluetooth anyway.
|
* level and we only care about battery level over bluetooth anyway.
|
||||||
*/
|
*/
|
||||||
if (device->vendor_id == USB_VENDOR_NINTENDO &&
|
if (device->vendor_id == USB_VENDOR_NINTENDO) {
|
||||||
(device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO ||
|
|
||||||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP ||
|
|
||||||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT ||
|
|
||||||
device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT)) {
|
|
||||||
input_mode = k_eSwitchInputReportIDs_FullControllerState;
|
input_mode = k_eSwitchInputReportIDs_FullControllerState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_mode == k_eSwitchInputReportIDs_FullControllerState &&
|
if (input_mode == k_eSwitchInputReportIDs_FullControllerState &&
|
||||||
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
|
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
|
||||||
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESRight) {
|
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 */
|
/* Use the right sensor in the combined Joy-Con pair */
|
||||||
if (!device->parent ||
|
if (!device->parent ||
|
||||||
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
|
ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
|
||||||
|
|
Loading…
Reference in New Issue