early-access version 2847

This commit is contained in:
pineappleEA
2022-07-19 05:48:31 +02:00
parent ba74a2373c
commit 05e3c38e7f
498 changed files with 16027 additions and 27028 deletions

View File

@@ -28,7 +28,6 @@
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_gamecontrollerdb.h"
#include "controller_type.h"
#include "usb_ids.h"
#if !SDL_EVENTS_DISABLED
@@ -587,12 +586,6 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
(vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) {
/* 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));
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_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));
} 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 {
/* All other controllers have the standard set of 19 buttons and 6 axes */
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,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string));
@@ -653,20 +646,12 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
*/
static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickGUID guid)
{
Uint16 vendor;
Uint16 product;
SDL_bool existing;
char mapping_string[1024];
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
if (GuessControllerType(vendor, product) == k_eControllerType_XInputSwitchController &&
SDL_GetHintBoolean(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, SDL_TRUE)) {
SDL_strlcat(mapping_string, "a:b1,b:b0,x:b3,y:b2,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
} else {
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
}
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
return SDL_PrivateAddMappingForGUID(guid, mapping_string,
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
@@ -711,20 +696,19 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
return s_pXInputMapping;
}
#endif
if (!mapping) {
if (SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForHIDAPIController(guid);
} else if (SDL_IsJoystickRAWINPUT(guid)) {
mapping = SDL_CreateMappingForRAWINPUTController(guid);
} else if (SDL_IsJoystickWGI(guid)) {
mapping = SDL_CreateMappingForWGIController(guid);
} else if (SDL_IsJoystickVirtual(guid)) {
/* We'll pick up a robust mapping in VIRTUAL_JoystickGetGamepadMapping */
#ifdef __ANDROID__
} else {
mapping = SDL_CreateMappingForAndroidController(guid);
if (!mapping && !SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForAndroidController(guid);
}
#endif
}
if (!mapping && SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForHIDAPIController(guid);
}
if (!mapping && SDL_IsJoystickRAWINPUT(guid)) {
mapping = SDL_CreateMappingForRAWINPUTController(guid);
}
if (!mapping && SDL_IsJoystickWGI(guid)) {
mapping = SDL_CreateMappingForWGIController(guid);
}
}
return mapping;
@@ -1274,11 +1258,6 @@ static ControllerMapping_t *SDL_PrivateGenerateAutomaticControllerMapping(const
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpdown", &raw_map->dpdown);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpleft", &raw_map->dpleft);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpright", &raw_map->dpright);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "misc1", &raw_map->misc1);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->paddle1);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->paddle2);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->paddle3);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->paddle4);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftx", &raw_map->leftx);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefty", &raw_map->lefty);
SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightx", &raw_map->rightx);
@@ -1753,20 +1732,6 @@ SDL_GameControllerNameForIndex(int device_index)
}
/*
* Get the implementation dependent path of a controller
*/
const char *
SDL_GameControllerPathForIndex(int device_index)
{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
return SDL_JoystickPathForIndex(device_index);
}
return NULL;
}
/**
* Get the type of a game controller.
*/
@@ -1855,10 +1820,12 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
}
#endif
#if defined(__ANDROID__)
if (name && SDL_strcmp(name, "uinput-fpc") == 0) {
/* The Google Pixel fingerprint sensor reports itself as a joystick */
return SDL_TRUE;
}
#endif
if (SDL_allowed_controllers.num_entries == 0 &&
SDL_ignored_controllers.num_entries == 0) {
@@ -2327,15 +2294,6 @@ SDL_GameControllerName(SDL_GameController *gamecontroller)
}
}
const char *
SDL_GameControllerPath(SDL_GameController *gamecontroller)
{
if (!gamecontroller)
return NULL;
return SDL_JoystickPath(SDL_GameControllerGetJoystick(gamecontroller));
}
SDL_GameControllerType
SDL_GameControllerGetType(SDL_GameController *gamecontroller)
{
@@ -2375,12 +2333,6 @@ SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller)
return SDL_JoystickGetProductVersion(SDL_GameControllerGetJoystick(gamecontroller));
}
Uint16
SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller)
{
return SDL_JoystickGetFirmwareVersion(SDL_GameControllerGetJoystick(gamecontroller));
}
const char *
SDL_GameControllerGetSerial(SDL_GameController *gamecontroller)
{

View File

@@ -187,7 +187,6 @@ static const char *s_ControllerMappings [] =
"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
"030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000380700006382000000000000,MLG Gamepad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
@@ -262,18 +261,11 @@ static const char *s_ControllerMappings [] =
"03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,",
"03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,",
"03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,",
"03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
"030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,",
"03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -449,7 +441,6 @@ static const char *s_ControllerMappings [] =
"030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
"03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -503,7 +494,7 @@ static const char *s_ControllerMappings [] =
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,",
#endif
#ifdef SDL_JOYSTICK_LINUX
#if defined(__LINUX__)
"xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -714,10 +705,6 @@ static const char *s_ControllerMappings [] =
"03000000c62400003a54000001010000,PowerA XBox One Controller,a:b0,b:b1,back:b6,dpdown:h0.7,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,",
"03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -754,11 +741,8 @@ static const char *s_ControllerMappings [] =
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,",
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
@@ -771,7 +755,6 @@ static const char *s_ControllerMappings [] =
"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
"030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,",
@@ -803,7 +786,6 @@ static const char *s_ControllerMappings [] =
"030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -905,6 +887,9 @@ static const char *s_ControllerMappings [] =
"050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
#endif
#if defined(SDL_JOYSTICK_VIRTUAL)
"00000000000000000000000000007601,Virtual Joystick,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,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
"default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
#endif
@@ -912,7 +897,7 @@ static const char *s_ControllerMappings [] =
"50535669746120436f6e74726f6c6c65,PSVita Controller,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
#endif
#if defined(SDL_JOYSTICK_PSP)
"505350206275696c74696e206a6f7970,PSP builtin joypad,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
"505350206275696c74696e206a6f7970,PSP builtin joypad,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b6,dpleft:b7,dpup:b8,dpright:b9,back:b10,start:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
#endif
"hidapi,*,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,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
NULL

View File

@@ -320,28 +320,6 @@ SDL_JoystickNameForIndex(int device_index)
return name;
}
/*
* Get the implementation dependent path of a joystick
*/
const char *
SDL_JoystickPathForIndex(int device_index)
{
SDL_JoystickDriver *driver;
const char *path = NULL;
SDL_LockJoysticks();
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
path = driver->GetDevicePath(device_index);
}
SDL_UnlockJoysticks();
/* FIXME: Really we should reference count this path so it doesn't go away after unlock */
if (!path) {
SDL_Unsupported();
}
return path;
}
/*
* Get the player index of a joystick, or -1 if it's not available
*/
@@ -408,8 +386,6 @@ SDL_JoystickOpen(int device_index)
SDL_Joystick *joystick;
SDL_Joystick *joysticklist;
const char *joystickname = NULL;
const char *joystickpath = NULL;
SDL_JoystickPowerLevel initial_power_level;
SDL_LockJoysticks();
@@ -459,13 +435,6 @@ SDL_JoystickOpen(int device_index)
joystick->name = NULL;
}
joystickpath = driver->GetDevicePath(device_index);
if (joystickpath) {
joystick->path = SDL_strdup(joystickpath);
} else {
joystick->path = NULL;
}
joystick->guid = driver->GetDeviceGUID(device_index);
if (joystick->naxes > 0) {
@@ -509,11 +478,6 @@ SDL_JoystickOpen(int device_index)
SDL_UnlockJoysticks();
/* send initial battery event */
initial_power_level = joystick->epowerlevel;
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
SDL_PrivateJoystickBatteryLevel(joystick, initial_power_level);
driver->Update(joystick);
return joystick;
@@ -522,23 +486,9 @@ SDL_JoystickOpen(int device_index)
int
SDL_JoystickAttachVirtual(SDL_JoystickType type,
int naxes, int nbuttons, int nhats)
{
SDL_VirtualJoystickDesc desc;
SDL_zero(desc);
desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION;
desc.type = (Uint16)type;
desc.naxes = (Uint16)naxes;
desc.nbuttons = (Uint16)nbuttons;
desc.nhats = (Uint16)nhats;
return SDL_JoystickAttachVirtualEx(&desc);
}
int
SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc)
{
#if SDL_JOYSTICK_VIRTUAL
return SDL_JoystickAttachVirtualInner(desc);
return SDL_JoystickAttachVirtualInner(type, naxes, nbuttons, nhats);
#else
return SDL_SetError("SDL not built with virtual-joystick support");
#endif
@@ -884,23 +834,6 @@ SDL_JoystickName(SDL_Joystick *joystick)
return joystick->name;
}
/*
* Get the implementation dependent path of this joystick
*/
const char *
SDL_JoystickPath(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return NULL;
}
if (!joystick->path) {
SDL_Unsupported();
return NULL;
}
return joystick->path;
}
/**
* Get the player index of an opened joystick, or -1 if it's not available
*/
@@ -953,18 +886,17 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
}
if (result == 0) {
joystick->low_frequency_rumble = low_frequency_rumble;
joystick->high_frequency_rumble = high_frequency_rumble;
/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->low_frequency_rumble = low_frequency_rumble;
joystick->high_frequency_rumble = high_frequency_rumble;
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else {
joystick->rumble_expiration = 0;
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->rumble_expiration) {
joystick->rumble_expiration = 1;
}
} else {
joystick->rumble_expiration = 0;
}
SDL_UnlockJoysticks();
@@ -988,18 +920,17 @@ SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
}
if (result == 0) {
joystick->left_trigger_rumble = left_rumble;
joystick->right_trigger_rumble = right_rumble;
/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->left_trigger_rumble = left_rumble;
joystick->right_trigger_rumble = right_rumble;
if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else {
joystick->trigger_rumble_expiration = 0;
if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else {
joystick->trigger_rumble_expiration = 0;
}
SDL_UnlockJoysticks();
@@ -1073,13 +1004,14 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
SDL_LockJoysticks();
isfreshvalue = red != joystick->led_red ||
green != joystick->led_green ||
blue != joystick->led_blue;
green != joystick->led_green ||
blue != joystick->led_blue;
if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) {
if ( isfreshvalue || SDL_TICKS_PASSED( SDL_GetTicks(), joystick->led_expiration ) ) {
result = joystick->driver->SetLED(joystick, red, green, blue);
joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS;
} else {
}
else {
/* Avoid spamming the driver */
result = 0;
}
@@ -1166,7 +1098,6 @@ SDL_JoystickClose(SDL_Joystick *joystick)
}
SDL_free(joystick->name);
SDL_free(joystick->path);
SDL_free(joystick->serial);
/* Free the data associated with this joystick */
@@ -1657,13 +1588,11 @@ SDL_JoystickUpdate(void)
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
if (joystick->attached) {
/* This driver should always be != NULL, but seeing a crash in the wild...? */
if (!joystick->driver) {
continue; /* nothing we can do, and other things use joystick->driver below here. */
/* This should always be true, but seeing a crash in the wild...? */
if (joystick->driver) {
joystick->driver->Update(joystick);
}
joystick->driver->Update(joystick);
if (joystick->delayed_guide_button) {
SDL_GameControllerHandleDelayedGuideButton(joystick);
}
@@ -1810,11 +1739,6 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
char *name;
size_t i, len;
/* Use the given name for the Nintendo Online NES Controllers */
if (SDL_strncmp(product_name, "NES Controller", 14) == 0) {
return SDL_strdup(product_name);
}
custom_name = GuessControllerName(vendor, product);
if (custom_name) {
return SDL_strdup(custom_name);
@@ -1837,48 +1761,23 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
if (*vendor_name && *product_name) {
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
name = (char *)SDL_malloc(len);
if (name) {
SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
if (!name) {
return NULL;
}
SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
} else if (*product_name) {
name = SDL_strdup(product_name);
} else if (vendor || product) {
/* Couldn't find a controller name, try to give it one based on device type */
switch (SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, NULL, SDL_TRUE)) {
case SDL_CONTROLLER_TYPE_XBOX360:
name = SDL_strdup("Xbox 360 Controller");
break;
case SDL_CONTROLLER_TYPE_XBOXONE:
name = SDL_strdup("Xbox One Controller");
break;
case SDL_CONTROLLER_TYPE_PS3:
name = SDL_strdup("PS3 Controller");
break;
case SDL_CONTROLLER_TYPE_PS4:
name = SDL_strdup("PS4 Controller");
break;
case SDL_CONTROLLER_TYPE_PS5:
name = SDL_strdup("PS5 Controller");
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
name = SDL_strdup("Nintendo Switch Pro Controller");
break;
default:
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (name) {
SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
}
break;
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (!name) {
return NULL;
}
SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
} else {
name = SDL_strdup("Controller");
}
if (!name) {
return NULL;
}
/* Trim trailing whitespace */
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
/* continue */
@@ -1927,85 +1826,9 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
}
SDL_GameControllerType
SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI)
SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product)
{
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
if (vendor == 0x0000 && product == 0x0000) {
/* Some devices are only identifiable by their name */
if (name &&
(SDL_strcmp(name, "Lic Pro Controller") == 0 ||
SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
SDL_strcmp(name, "Wireless Gamepad") == 0)) {
/* HORI or PowerA Switch Pro Controller clone */
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
}
} else if (vendor == 0x0001 && product == 0x0001) {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
} else if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
} else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) ||
(vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) {
type = SDL_CONTROLLER_TYPE_AMAZON_LUNA;
} else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA;
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
} else {
switch (GuessControllerType(vendor, product)) {
case k_eControllerType_XBox360Controller:
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
case k_eControllerType_XBoxOneController:
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
case k_eControllerType_PS3Controller:
type = SDL_CONTROLLER_TYPE_PS3;
break;
case k_eControllerType_PS4Controller:
type = SDL_CONTROLLER_TYPE_PS4;
break;
case k_eControllerType_PS5Controller:
type = SDL_CONTROLLER_TYPE_PS5;
break;
case k_eControllerType_XInputPS4Controller:
if (forUI) {
type = SDL_CONTROLLER_TYPE_PS4;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
case k_eControllerType_SwitchProController:
case k_eControllerType_SwitchInputOnlyController:
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
case k_eControllerType_XInputSwitchController:
if (forUI) {
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
/* We always support the Nintendo Online NES Controllers */
if (name && SDL_strncmp(name, "NES Controller", 14) == 0) {
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
}
break;
default:
break;
}
}
return type;
return SDL_GetJoystickGameControllerType(NULL, vendor, product, -1, 0, 0, 0);
}
SDL_GameControllerType
@@ -2015,24 +1838,154 @@ SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *nam
Uint16 vendor, product;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE);
type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (SDL_IsJoystickXInput(guid)) {
/* This is probably an Xbox One controller */
return SDL_CONTROLLER_TYPE_XBOXONE;
}
if (SDL_IsJoystickVirtual(guid)) {
return SDL_CONTROLLER_TYPE_VIRTUAL;
}
}
return type;
}
SDL_bool
SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id)
SDL_GameControllerType
SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
return (eType == k_eControllerType_XBoxOneController);
static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
static const int XB360_IFACE_SUBCLASS = 93;
static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
static const int XBONE_IFACE_SUBCLASS = 71;
static const int XBONE_IFACE_PROTOCOL = 208;
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
/* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XB360_IFACE_SUBCLASS &&
(interface_protocol == XB360_IFACE_PROTOCOL ||
interface_protocol == XB360W_IFACE_PROTOCOL)) {
static const int SUPPORTED_VENDORS[] = {
0x0079, /* GPD Win 2 */
0x044f, /* Thrustmaster */
0x045e, /* Microsoft */
0x046d, /* Logitech */
0x056e, /* Elecom */
0x06a3, /* Saitek */
0x0738, /* Mad Catz */
0x07ff, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1038, /* SteelSeries */
0x11c9, /* Nacon */
0x12ab, /* Unknown */
0x1430, /* RedOctane */
0x146b, /* BigBen */
0x1532, /* Razer Sabertooth */
0x15e4, /* Numark */
0x162e, /* Joytech */
0x1689, /* Razer Onza */
0x1949, /* Lab126, Inc. */
0x1bad, /* Harmonix */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
}
}
}
if (interface_number == 0 &&
interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XBONE_IFACE_SUBCLASS &&
interface_protocol == XBONE_IFACE_PROTOCOL) {
static const int SUPPORTED_VENDORS[] = {
0x045e, /* Microsoft */
0x0738, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1532, /* Razer Wildcat */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2e24, /* Hyperkin */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
}
}
}
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (vendor == 0x0000 && product == 0x0000) {
/* Some devices are only identifiable by their name */
if (name &&
(SDL_strcmp(name, "Lic Pro Controller") == 0 ||
SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
SDL_strcmp(name, "Wireless Gamepad") == 0)) {
/* HORI or PowerA Switch Pro Controller clone */
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
} else if (name && SDL_strcmp(name, "Virtual Joystick") == 0) {
type = SDL_CONTROLLER_TYPE_VIRTUAL;
} else {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
}
} else if (vendor == 0x0001 && product == 0x0001) {
type = SDL_CONTROLLER_TYPE_UNKNOWN;
} else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) ||
(vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) {
type = SDL_CONTROLLER_TYPE_AMAZON_LUNA;
} else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) {
type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA;
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
} else {
switch (GuessControllerType(vendor, product)) {
case k_eControllerType_XBox360Controller:
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
case k_eControllerType_XBoxOneController:
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
case k_eControllerType_PS3Controller:
type = SDL_CONTROLLER_TYPE_PS3;
break;
case k_eControllerType_PS4Controller:
type = SDL_CONTROLLER_TYPE_PS4;
break;
case k_eControllerType_PS5Controller:
type = SDL_CONTROLLER_TYPE_PS5;
break;
case k_eControllerType_SwitchProController:
case k_eControllerType_SwitchInputOnlyController:
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
break;
default:
type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
}
}
}
return type;
}
SDL_bool
@@ -2196,14 +2149,10 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */
MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */
MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
MAKE_VIDPID(0x044f, 0xb696), /* Thrustmaster T248 */
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS (normal mode) */
MAKE_VIDPID(0x044f, 0xb66f), /* Thrustmaster T300RS (advanced mode) */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster T300RS (PS4 mode) */
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */
MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
@@ -2241,12 +2190,6 @@ static SDL_bool SDL_IsJoystickProductArcadeStick(Uint32 vidpid)
MAKE_VIDPID(0x1532, 0x0a00), /* Razer Atrox Arcade Stick */
MAKE_VIDPID(0x0f0d, 0x00aa), /* HORI Real Arcade Pro V Hayabusa in Switch Mode */
MAKE_VIDPID(0x20d6, 0xa715), /* PowerA Nintendo Switch Fusion Arcade Stick */
MAKE_VIDPID(0x2c22, 0x2300), /* Qanba Obsidian Arcade Joystick in PS4 Mode */
MAKE_VIDPID(0x2c22, 0x2302), /* Qanba Obsidian Arcade Joystick in PS3 Mode */
MAKE_VIDPID(0x2c22, 0x2303), /* Qanba Obsidian Arcade Joystick in PC Mode */
MAKE_VIDPID(0x2c22, 0x2500), /* Qanba Dragon Arcade Joystick in PS4 Mode */
MAKE_VIDPID(0x2c22, 0x2502), /* Qanba Dragon Arcade Joystick in PS3 Mode */
MAKE_VIDPID(0x2c22, 0x2503), /* Qanba Dragon Arcade Joystick in PC Mode */
};
int i;
@@ -2495,24 +2438,11 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
/* Additional entries */
/*****************************************************************/
MAKE_VIDPID(0x04d9, 0x8008), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa292), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x04d9, 0xa293), /* OBINLB USB-HID Keyboard (Anne Pro II) */
MAKE_VIDPID(0x1532, 0x0266), /* Razer Huntman V2 Analog, non-functional DInput device */
MAKE_VIDPID(0x1532, 0x0282), /* Razer Huntman Mini Analog, non-functional DInput device */
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard */
MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Mouse */
MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */
};
static Uint32 rog_chakram_list[] = {
MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Core Mouse */
MAKE_VIDPID(0x0b05, 0x18e3), /* ROG Chakram (wired) Mouse */
MAKE_VIDPID(0x0b05, 0x18e5), /* ROG Chakram (wireless) Mouse */
MAKE_VIDPID(0x0b05, 0x1a18), /* ROG Chakram X (wired) Mouse */
MAKE_VIDPID(0x0b05, 0x1a1a), /* ROG Chakram X (wireless) Mouse */
MAKE_VIDPID(0x0b05, 0x1a1c), /* ROG Chakram X (Bluetooth) Mouse */
};
unsigned int i;
Uint32 id;
Uint16 vendor;
@@ -2528,20 +2458,14 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
return SDL_TRUE;
}
}
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_ROG_CHAKRAM, SDL_FALSE)) {
for (i = 0; i < SDL_arraysize(rog_chakram_list); ++i) {
if (id == rog_chakram_list[i]) {
return SDL_TRUE;
}
}
}
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_FALSE);
type = SDL_GetJoystickGameControllerType(name, vendor, product, -1, 0, 0, 0);
if ((type == SDL_CONTROLLER_TYPE_PS4 || type == SDL_CONTROLLER_TYPE_PS5) && SDL_IsPS4RemapperRunning()) {
return SDL_TRUE;
}
if (SDL_ShouldIgnoreGameController(name, guid)) {
if (SDL_IsGameControllerNameAndGUID(name, guid) &&
SDL_ShouldIgnoreGameController(name, guid)) {
return SDL_TRUE;
}
@@ -2674,14 +2598,6 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
return version;
}
Uint16 SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return 0;
}
return joystick->firmware_version;
}
const char *SDL_JoystickGetSerial(SDL_Joystick *joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
@@ -2707,31 +2623,74 @@ SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
/* convert the guid to a printable string */
void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID)
{
SDL_GUIDToString(guid, pszGUID, cbGUID);
static const char k_rgchHexToASCII[] = "0123456789abcdef";
int i;
if ((pszGUID == NULL) || (cbGUID <= 0)) {
return;
}
for (i = 0; i < sizeof(guid.data) && i < (cbGUID-1)/2; i++) {
/* each input byte writes 2 ascii chars, and might write a null byte. */
/* If we don't have room for next input byte, stop */
unsigned char c = guid.data[i];
*pszGUID++ = k_rgchHexToASCII[c >> 4];
*pszGUID++ = k_rgchHexToASCII[c & 0x0F];
}
*pszGUID = '\0';
}
/*-----------------------------------------------------------------------------
* Purpose: Returns the 4 bit nibble for a hex character
* Input : c -
* Output : unsigned char
*-----------------------------------------------------------------------------*/
static unsigned char nibble(unsigned char c)
{
if ((c >= '0') && (c <= '9')) {
return (c - '0');
}
if ((c >= 'A') && (c <= 'F')) {
return (c - 'A' + 0x0a);
}
if ((c >= 'a') && (c <= 'f')) {
return (c - 'a' + 0x0a);
}
/* received an invalid character, and no real way to return an error */
/* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */
return 0;
}
/* convert the string version of a joystick guid to the struct */
SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID)
{
return SDL_GUIDFromString(pchGUID);
SDL_JoystickGUID guid;
int maxoutputbytes= sizeof(guid);
size_t len = SDL_strlen(pchGUID);
Uint8 *p;
size_t i;
/* Make sure it's even */
len = (len) & ~0x1;
SDL_memset(&guid, 0x00, sizeof(guid));
p = (Uint8 *)&guid;
for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i+=2, p++) {
*p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i+1]);
}
return guid;
}
/* update the power level for this joystick */
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
{
SDL_assert(joystick->ref_count); /* make sure we are calling this only for update, not for initialisation */
if (ePowerLevel != joystick->epowerlevel) {
#if !SDL_EVENTS_DISABLED
if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_JOYBATTERYUPDATED;
event.jbattery.which = joystick->instance_id;
event.jbattery.level = ePowerLevel;
SDL_PushEvent(&event);
}
#endif /* !SDL_EVENTS_DISABLED */
joystick->epowerlevel = ePowerLevel;
}
joystick->epowerlevel = ePowerLevel;
}
/* return its power level */
@@ -2748,7 +2707,9 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
SDL_JoystickTouchpadInfo *touchpad_info;
SDL_JoystickTouchpadFingerInfo *finger_info;
int posted;
#if !SDL_EVENTS_DISABLED
Uint32 event_type;
#endif
if (touchpad < 0 || touchpad >= joystick->ntouchpads) {
return 0;
@@ -2792,6 +2753,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
}
}
#if !SDL_EVENTS_DISABLED
if (state == finger_info->state) {
event_type = SDL_CONTROLLERTOUCHPADMOTION;
} else if (state) {
@@ -2799,6 +2761,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
} else {
event_type = SDL_CONTROLLERTOUCHPADUP;
}
#endif
/* We ignore events if we don't have keyboard focus, except for touch release */
if (SDL_PrivateJoystickShouldIgnoreEvent()) {

View File

@@ -58,11 +58,9 @@ extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint1
extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name);
/* Function to return the type of a controller */
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI);
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product);
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);
/* Function to return whether a joystick is an Xbox One controller */
extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol);
/* Function to return whether a joystick is an Xbox One Elite controller */
extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id);
@@ -170,11 +168,6 @@ typedef struct _SDL_GamepadMapping
SDL_InputMapping dpdown;
SDL_InputMapping dpleft;
SDL_InputMapping dpright;
SDL_InputMapping misc1;
SDL_InputMapping paddle1;
SDL_InputMapping paddle2;
SDL_InputMapping paddle3;
SDL_InputMapping paddle4;
SDL_InputMapping leftx;
SDL_InputMapping lefty;
SDL_InputMapping rightx;

View File

@@ -65,10 +65,8 @@ struct _SDL_Joystick
{
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Joystick name - system dependent */
char *path; /* Joystick path - system dependent */
char *serial; /* Joystick serial */
SDL_JoystickGUID guid; /* Joystick guid */
Uint16 firmware_version; /* Firmware version, if available */
int naxes; /* Number of axis controls on the joystick */
SDL_JoystickAxisInfo *axes;
@@ -120,7 +118,6 @@ struct _SDL_Joystick
};
/* Device bus definitions */
#define SDL_HARDWARE_BUS_VIRTUAL 0x00
#define SDL_HARDWARE_BUS_USB 0x03
#define SDL_HARDWARE_BUS_BLUETOOTH 0x05
@@ -149,9 +146,6 @@ typedef struct _SDL_JoystickDriver
/* Function to get the device-dependent name of a joystick */
const char *(*GetDeviceName)(int device_index);
/* Function to get the device-dependent path of a joystick */
const char *(*GetDevicePath)(int device_index);
/* Function to get the player index of a joystick */
int (*GetDevicePlayerIndex)(int device_index);

View File

@@ -103,7 +103,6 @@ keycode_to_SDL(int keycode)
case AKEYCODE_BUTTON_THUMBR:
button = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
break;
case AKEYCODE_MENU:
case AKEYCODE_BUTTON_START:
button = SDL_CONTROLLER_BUTTON_START;
break;
@@ -558,12 +557,6 @@ ANDROID_JoystickGetDeviceName(int device_index)
return JoystickByDevIndex(device_index)->name;
}
static const char *
ANDROID_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -719,7 +712,6 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetCount,
ANDROID_JoystickDetect,
ANDROID_JoystickGetDeviceName,
ANDROID_JoystickGetDevicePath,
ANDROID_JoystickGetDevicePlayerIndex,
ANDROID_JoystickSetDevicePlayerIndex,
ANDROID_JoystickGetDeviceGUID,

View File

@@ -268,15 +268,9 @@ static const char *
BSD_JoystickGetDeviceName(int device_index)
{
if (joydevnames[device_index] != NULL) {
return joydevnames[device_index];
return (joydevnames[device_index]);
}
return joynames[device_index];
}
static const char *
BSD_JoystickGetDevicePath(int device_index)
{
return joynames[device_index];
return (joynames[device_index]);
}
static int
@@ -813,7 +807,6 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickGetCount,
BSD_JoystickDetect,
BSD_JoystickGetDeviceName,
BSD_JoystickGetDevicePath,
BSD_JoystickGetDevicePlayerIndex,
BSD_JoystickSetDevicePlayerIndex,
BSD_JoystickGetDeviceGUID,

View File

@@ -53,9 +53,8 @@ typedef enum
k_eControllerType_SwitchJoyConPair = 41,
k_eControllerType_SwitchInputOnlyController = 42,
k_eControllerType_MobileTouch = 43,
k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Nintendo Switch style controllers as using XInput instead of the Nintendo Switch protocol
k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Switch-compatible controllers as not supporting Switch controller protocol
k_eControllerType_PS5Controller = 45,
k_eControllerType_XInputPS4Controller = 46, // Client-side only, used to mark DualShock 4 style controllers using XInput instead of the DualShock 4 controller protocol
k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value
// Keyboards and Mice
@@ -63,6 +62,7 @@ typedef enum
k_eControllertype_GenericMouse = 800,
} EControllerType;
#define MAKE_CONTROLLER_ID( nVID, nPID ) (unsigned int)( (unsigned int)nVID << 16 | (unsigned int)nPID )
typedef struct
{
unsigned int m_unDeviceID;
@@ -70,10 +70,683 @@ typedef struct
const char *m_pszName;
} ControllerDescription_t;
static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick
{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3
{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1
{ MAKE_CONTROLLER_ID( 0x054c, 0x0268 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller
{ MAKE_CONTROLLER_ID( 0x056e, 0x200f ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x056e, 0x2013 ), k_eControllerType_PS3Controller, NULL }, // JC-U4113SBK
{ MAKE_CONTROLLER_ID( 0x05b8, 0x1004 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x05b8, 0x1006 ), k_eControllerType_PS3Controller, NULL }, // JC-U3412SBK
{ MAKE_CONTROLLER_ID( 0x06a3, 0xf622 ), k_eControllerType_PS3Controller, NULL }, // Cyborg V3
{ MAKE_CONTROLLER_ID( 0x0738, 0x3180 ), k_eControllerType_PS3Controller, NULL }, // Mad Catz Alpha PS3 mode
{ MAKE_CONTROLLER_ID( 0x0738, 0x3250 ), k_eControllerType_PS3Controller, NULL }, // madcats fightpad pro ps3
{ MAKE_CONTROLLER_ID( 0x0738, 0x8180 ), k_eControllerType_PS3Controller, NULL }, // Mad Catz Alpha PS4 mode (no touchpad on device)
{ MAKE_CONTROLLER_ID( 0x0738, 0x8838 ), k_eControllerType_PS3Controller, NULL }, // Madcatz Fightstick Pro
{ MAKE_CONTROLLER_ID( 0x0810, 0x0001 ), k_eControllerType_PS3Controller, NULL }, // actually ps2 - maybe break out later
{ MAKE_CONTROLLER_ID( 0x0810, 0x0003 ), k_eControllerType_PS3Controller, NULL }, // actually ps2 - maybe break out later
{ MAKE_CONTROLLER_ID( 0x0925, 0x0005 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller
{ MAKE_CONTROLLER_ID( 0x0925, 0x8866 ), k_eControllerType_PS3Controller, NULL }, // PS2 maybe break out later
{ MAKE_CONTROLLER_ID( 0x0925, 0x8888 ), k_eControllerType_PS3Controller, NULL }, // Actually ps2 -maybe break out later Lakeview Research WiseGroup Ltd, MP-8866 Dual Joypad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0109 ), k_eControllerType_PS3Controller, NULL }, // PDP Versus Fighting Pad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x011e ), k_eControllerType_PS3Controller, NULL }, // Rock Candy PS4
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0128 ), k_eControllerType_PS3Controller, NULL }, // Rock Candy PS3
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS3Controller, NULL }, // Victrix Pro FS (PS4 peripheral but no trackpad/lightbar)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0214 ), k_eControllerType_PS3Controller, NULL }, // afterglow ps3
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1314 ), k_eControllerType_PS3Controller, NULL }, // PDP Afterglow Wireless PS3 controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x6302 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x0e8f, 0x0008 ), k_eControllerType_PS3Controller, NULL }, // Green Asia
{ MAKE_CONTROLLER_ID( 0x0e8f, 0x3075 ), k_eControllerType_PS3Controller, NULL }, // SpeedLink Strike FX
{ MAKE_CONTROLLER_ID( 0x0e8f, 0x310d ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0009 ), k_eControllerType_PS3Controller, NULL }, // HORI BDA GP1
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x004d ), k_eControllerType_PS3Controller, NULL }, // Horipad 3
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005e ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting commander ps4
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005f ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting commander ps3
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006a ), k_eControllerType_PS3Controller, NULL }, // Real Arcade Pro 4
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006e ), k_eControllerType_PS3Controller, NULL }, // HORI horipad4 ps3
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0085 ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Commander PS3
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0086 ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Commander PC (Uses the Xbox 360 protocol, but has PS3 buttons)
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0087 ), k_eControllerType_PS3Controller, NULL }, // HORI fighting mini stick
{ MAKE_CONTROLLER_ID( 0x0f30, 0x1100 ), k_eControllerType_PS3Controller, NULL }, // Quanba Q1 fight stick
{ MAKE_CONTROLLER_ID( 0x11ff, 0x3331 ), k_eControllerType_PS3Controller, NULL }, // SRXJ-PH2400
{ MAKE_CONTROLLER_ID( 0x1345, 0x1000 ), k_eControllerType_PS3Controller, NULL }, // PS2 ACME GA-D5
{ MAKE_CONTROLLER_ID( 0x1345, 0x6005 ), k_eControllerType_PS3Controller, NULL }, // ps2 maybe break out later
{ MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x146b, 0x5500 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x1a34, 0x0836 ), k_eControllerType_PS3Controller, NULL }, // Afterglow PS3
{ MAKE_CONTROLLER_ID( 0x20bc, 0x5500 ), k_eControllerType_PS3Controller, NULL }, // ShanWan PS3
{ MAKE_CONTROLLER_ID( 0x20d6, 0x576d ), k_eControllerType_PS3Controller, NULL }, // Power A PS3
{ MAKE_CONTROLLER_ID( 0x20d6, 0xca6d ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x2563, 0x0523 ), k_eControllerType_PS3Controller, NULL }, // Digiflip GP006
{ MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller, NULL }, // gioteck vx2
{ MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller, NULL }, //
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2000 ), k_eControllerType_PS3Controller, NULL }, // Quanba Drone
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x8380, 0x0003 ), k_eControllerType_PS3Controller, NULL }, // BTP 2163
{ MAKE_CONTROLLER_ID( 0x8888, 0x0308 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller
extern EControllerType GuessControllerType( int nVID, int nPID );
extern const char *GuessControllerName( int nVID, int nPID );
{ MAKE_CONTROLLER_ID( 0x0079, 0x181b ), k_eControllerType_PS4Controller, NULL }, // Venom Arcade Stick - XXX:this may not work and may need to be called a ps3 controller
{ MAKE_CONTROLLER_ID( 0x054c, 0x05c4 ), k_eControllerType_PS4Controller, NULL }, // Sony PS4 Controller
{ MAKE_CONTROLLER_ID( 0x054c, 0x05c5 ), k_eControllerType_PS4Controller, NULL }, // STRIKEPAD PS4 Grip Add-on
{ MAKE_CONTROLLER_ID( 0x054c, 0x09cc ), k_eControllerType_PS4Controller, NULL }, // Sony PS4 Slim Controller
{ MAKE_CONTROLLER_ID( 0x054c, 0x0ba0 ), k_eControllerType_PS4Controller, NULL }, // Sony PS4 Controller (Wireless dongle)
{ MAKE_CONTROLLER_ID( 0x0738, 0x8250 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightPad Pro PS4
{ MAKE_CONTROLLER_ID( 0x0738, 0x8384 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE S+ PS4
{ MAKE_CONTROLLER_ID( 0x0738, 0x8480 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE 2 PS4
{ MAKE_CONTROLLER_ID( 0x0738, 0x8481 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE 2+ PS4
{ MAKE_CONTROLLER_ID( 0x0C12, 0x0E10 ), k_eControllerType_PS4Controller, NULL }, // Armor Armor 3 Pad PS4
{ MAKE_CONTROLLER_ID( 0x0C12, 0x1CF6 ), k_eControllerType_PS4Controller, NULL }, // EMIO PS4 Elite Controller
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e15 ), k_eControllerType_PS4Controller, NULL }, // Game:Pad 4
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller, NULL }, // Hitbox Arcade Stick
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0055 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS Plus
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0084 ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Commander PS4
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x008a ), k_eControllerType_PS4Controller, NULL }, // HORI Real Arcade Pro 4
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x009c ), k_eControllerType_PS4Controller, NULL }, // HORI TAC PRO mousething
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a0 ), k_eControllerType_PS4Controller, NULL }, // HORI TAC4 mousething
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ee ), k_eControllerType_PS4Controller, NULL }, // Hori mini wired https://www.playstation.com/en-us/explore/accessories/gaming-controllers/mini-wired-gamepad/
{ MAKE_CONTROLLER_ID( 0x11c0, 0x4001 ), k_eControllerType_PS4Controller, NULL }, // "PS4 Fun Controller" added from user log
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller, NULL }, // Nacon Revolution Pro Controller - has gyro
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller, NULL }, // Nacon Revolution Pro Controller v2 - has gyro
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Infinite - has gyro
{ MAKE_CONTROLLER_ID( 0x1532, 0X0401 ), k_eControllerType_PS4Controller, NULL }, // Razer Panthera PS4 Controller
{ MAKE_CONTROLLER_ID( 0x1532, 0x1000 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju PS4 Controller
{ MAKE_CONTROLLER_ID( 0x1532, 0x1004 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate USB
{ MAKE_CONTROLLER_ID( 0x1532, 0x1007 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Tournament edition USB
{ MAKE_CONTROLLER_ID( 0x1532, 0x1008 ), k_eControllerType_PS4Controller, NULL }, // Razer Panthera Evo Fightstick
{ MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate BT
{ MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Tournament edition BT
{ MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller, NULL }, // Razer RAION Fightpad - Trackpad, no gyro, lightbar hardcoded to green
{ MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller, NULL }, // Armor 3 or Level Up Cobra - At least one variant has gyro
{ MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller, NULL }, // Astro C40
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro Fightstick w/ Touchpad for PS4
// Removing the Giotek because there were a bunch of help tickets from users w/ issues including from non-PS4 controller users. This VID/PID is probably used in different FW's
// { MAKE_CONTROLLER_ID( 0x7545, 0x1122 ), k_eControllerType_PS4Controller, NULL }, // Giotek VX4 - trackpad/gyro don't work. Had to not filter on interface info. Light bar is flaky, but works.
{ MAKE_CONTROLLER_ID( 0x044f, 0xd00e ), k_eControllerType_PS4Controller, NULL }, // Thrustmast Eswap Pro - No gyro and lightbar doesn't change color. Works otherwise
{ MAKE_CONTROLLER_ID( 0x0c12, 0x1e10 ), k_eControllerType_PS4Controller, NULL }, // P4 Wired Gamepad generic knock off - lightbar but not trackpad or gyro
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d09 ), k_eControllerType_PS4Controller, NULL }, // NACON Daija Fight Stick - touchpad but no gyro/rumble
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Unlimited
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d08 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Unlimited Wireless Dongle
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d06 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller Wireless Dongle -- show up as ps4 until you connect controller to it then it reboots into Xbox controller with different vvid/pid
{ MAKE_CONTROLLER_ID( 0x146b, 0x1103 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller -- on windows this doesn't enumerate
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0123 ), k_eControllerType_PS4Controller, NULL }, // HORI Wireless Controller Light (Japan only) - only over bt- over usb is xbox and pid 0x0124
{ MAKE_CONTROLLER_ID( 0x146b, 0x0d13 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution 3
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e20 ), k_eControllerType_PS4Controller, NULL }, // Brook Mars Controller - needs FW update to show up as Ps4 controller on PC. Has Gyro but touchpad is a single button.
#endif // CONTROLLER_TYPE_H
{ MAKE_CONTROLLER_ID( 0x054c, 0x0ce6 ), k_eControllerType_PS5Controller, NULL }, // Sony PS5 Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x0006 ), k_eControllerType_UnknownNonSteamController, NULL }, // DragonRise Generic USB PCB, sometimes configured as a PC Twin Shock Controller - looks like a DS3 but the face buttons are 1-4 instead of symbols
{ MAKE_CONTROLLER_ID( 0x0079, 0x18d4 ), k_eControllerType_XBox360Controller, NULL }, // GPD Win 2 X-Box Controller
{ MAKE_CONTROLLER_ID( 0x03eb, 0xff02 ), k_eControllerType_XBox360Controller, NULL }, // Wooting Two
{ MAKE_CONTROLLER_ID( 0x044f, 0xb326 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster Gamepad GP XID
{ MAKE_CONTROLLER_ID( 0x045e, 0x028e ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x028f ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad v2
{ MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (XBOX)
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Big Button IR
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Wireless Controller with XUSB driver on Windows
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a9 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (third party knockoff)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F310
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21e ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F510
{ MAKE_CONTROLLER_ID( 0x046d, 0xc21f ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F710
{ MAKE_CONTROLLER_ID( 0x046d, 0xc242 ), k_eControllerType_XBox360Controller, NULL }, // Logitech Chillstream Controller
{ MAKE_CONTROLLER_ID( 0x056e, 0x2004 ), k_eControllerType_XBox360Controller, NULL }, // Elecom JC-U3613M
{ MAKE_CONTROLLER_ID( 0x06a3, 0xf51a ), k_eControllerType_XBox360Controller, NULL }, // Saitek P3600
{ MAKE_CONTROLLER_ID( 0x0738, 0x4716 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Wired Xbox 360 Controller
{ MAKE_CONTROLLER_ID( 0x0738, 0x4718 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Street Fighter IV FightStick SE
{ MAKE_CONTROLLER_ID( 0x0738, 0x4726 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller
{ MAKE_CONTROLLER_ID( 0x0738, 0x4728 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Street Fighter IV FightPad
{ MAKE_CONTROLLER_ID( 0x0738, 0x4736 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz MicroCon Gamepad
{ MAKE_CONTROLLER_ID( 0x0738, 0x4738 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Wired Xbox 360 Controller (SFIV)
{ MAKE_CONTROLLER_ID( 0x0738, 0x4740 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Beat Pad
{ MAKE_CONTROLLER_ID( 0x0738, 0xb726 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox controller - MW2
{ MAKE_CONTROLLER_ID( 0x0738, 0xbeef ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz JOYTECH NEO SE Advanced GamePad
{ MAKE_CONTROLLER_ID( 0x0738, 0xcb02 ), k_eControllerType_XBox360Controller, NULL }, // Saitek Cyborg Rumble Pad - PC/Xbox 360
{ MAKE_CONTROLLER_ID( 0x0738, 0xcb03 ), k_eControllerType_XBox360Controller, NULL }, // Saitek P3200 Rumble Pad - PC/Xbox 360
{ MAKE_CONTROLLER_ID( 0x0738, 0xf738 ), k_eControllerType_XBox360Controller, NULL }, // Super SFIV FightStick TE S
{ MAKE_CONTROLLER_ID( 0x0955, 0x7210 ), k_eControllerType_XBox360Controller, NULL }, // Nvidia Shield local controller
{ MAKE_CONTROLLER_ID( 0x0955, 0xb400 ), k_eControllerType_XBox360Controller, NULL }, // NVIDIA Shield streaming controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0105 ), k_eControllerType_XBox360Controller, NULL }, // HSM3 Xbox360 dancepad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0113 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Afterglow" }, // PDP Afterglow Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x011f ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Rock Candy" }, // PDP Rock Candy Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0125 ), k_eControllerType_XBox360Controller, "PDP INJUSTICE FightStick" }, // PDP INJUSTICE FightStick for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0127 ), k_eControllerType_XBox360Controller, "PDP INJUSTICE FightPad" }, // PDP INJUSTICE FightPad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0131 ), k_eControllerType_XBox360Controller, "PDP EA Soccer Controller" }, // PDP EA Soccer Gamepad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0133 ), k_eControllerType_XBox360Controller, "PDP Battlefield 4 Controller" }, // PDP Battlefield 4 Gamepad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0143 ), k_eControllerType_XBox360Controller, "PDP MK X Fight Stick" }, // PDP MK X Fight Stick for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0147 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Marvel Controller" }, // PDP Marvel Controller for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0201 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Controller" }, // PDP Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0213 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Afterglow" }, // PDP Afterglow Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x021f ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Rock Candy" }, // PDP Rock Candy Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0301 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Controller" }, // PDP Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0313 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Afterglow" }, // PDP Afterglow Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0314 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Afterglow" }, // PDP Afterglow Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0401 ), k_eControllerType_XBox360Controller, "PDP Xbox 360 Controller" }, // PDP Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0413 ), k_eControllerType_XBox360Controller, NULL }, // PDP Afterglow AX.1 (unlisted)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0501 ), k_eControllerType_XBox360Controller, NULL }, // PDP Xbox 360 Controller (unlisted)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0xf900 ), k_eControllerType_XBox360Controller, NULL }, // PDP Afterglow AX.1 (unlisted)
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x000a ), k_eControllerType_XBox360Controller, NULL }, // Hori Co. DOA4 FightStick
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x000c ), k_eControllerType_XBox360Controller, NULL }, // Hori PadEX Turbo
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x000d ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Stick EX2
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0016 ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro.EX
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x001b ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro VX
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x008c ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro 4
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00db ), k_eControllerType_XBox360Controller, "HORI Slime Controller" }, // Hori Dragon Quest Slime Controller
{ MAKE_CONTROLLER_ID( 0x1038, 0x1430 ), k_eControllerType_XBox360Controller, "SteelSeries Stratus Duo" }, // SteelSeries Stratus Duo
{ MAKE_CONTROLLER_ID( 0x1038, 0x1431 ), k_eControllerType_XBox360Controller, "SteelSeries Stratus Duo" }, // SteelSeries Stratus Duo
{ MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_XBox360Controller, NULL }, // SteelSeries Nimbus/Stratus XL
{ MAKE_CONTROLLER_ID( 0x11c9, 0x55f0 ), k_eControllerType_XBox360Controller, NULL }, // Nacon GC-100XF
{ MAKE_CONTROLLER_ID( 0x12ab, 0x0004 ), k_eControllerType_XBox360Controller, NULL }, // Honey Bee Xbox360 dancepad
{ MAKE_CONTROLLER_ID( 0x12ab, 0x0301 ), k_eControllerType_XBox360Controller, NULL }, // PDP AFTERGLOW AX.1
{ MAKE_CONTROLLER_ID( 0x12ab, 0x0303 ), k_eControllerType_XBox360Controller, NULL }, // Mortal Kombat Klassic FightStick
{ MAKE_CONTROLLER_ID( 0x1430, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // RedOctane Controller Adapter
{ MAKE_CONTROLLER_ID( 0x1430, 0x4748 ), k_eControllerType_XBox360Controller, NULL }, // RedOctane Guitar Hero X-plorer
{ MAKE_CONTROLLER_ID( 0x1430, 0xf801 ), k_eControllerType_XBox360Controller, NULL }, // RedOctane Controller
{ MAKE_CONTROLLER_ID( 0x146b, 0x0601 ), k_eControllerType_XBox360Controller, NULL }, // BigBen Interactive XBOX 360 Controller
// { MAKE_CONTROLLER_ID( 0x1532, 0x0037 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth
{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f00 ), k_eControllerType_XBox360Controller, NULL }, // Power A Mini Pro Elite
{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f0a ), k_eControllerType_XBox360Controller, NULL }, // Xbox Airflo wired controller
{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f10 ), k_eControllerType_XBox360Controller, NULL }, // Batarang Xbox 360 controller
{ MAKE_CONTROLLER_ID( 0x162e, 0xbeef ), k_eControllerType_XBox360Controller, NULL }, // Joytech Neo-Se Take2
{ MAKE_CONTROLLER_ID( 0x1689, 0xfd00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Tournament Edition
{ MAKE_CONTROLLER_ID( 0x1689, 0xfd01 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Classic Edition
{ MAKE_CONTROLLER_ID( 0x1689, 0xfe00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth
{ MAKE_CONTROLLER_ID( 0x1949, 0x041a ), k_eControllerType_XBox360Controller, "Amazon Luna Controller" }, // Amazon Luna Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0x0002 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Guitar
{ MAKE_CONTROLLER_ID( 0x1bad, 0x0003 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Drumkit
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf016 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf018 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Street Fighter IV SE Fighting Stick
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf019 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Brawlstick for Xbox 360
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf021 ), k_eControllerType_XBox360Controller, NULL }, // Mad Cats Ghost Recon FS GamePad
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf023 ), k_eControllerType_XBox360Controller, NULL }, // MLG Pro Circuit Controller (Xbox)
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf025 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Call Of Duty
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf027 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz FPS Pro
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf028 ), k_eControllerType_XBox360Controller, NULL }, // Street Fighter IV FightPad
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf02e ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Fightpad
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf036 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz MicroCon GamePad Pro
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf038 ), k_eControllerType_XBox360Controller, NULL }, // Street Fighter IV FightStick TE
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf039 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz MvC2 TE
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf03a ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz SFxT Fightstick Pro
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf03d ), k_eControllerType_XBox360Controller, NULL }, // Street Fighter IV Arcade Stick TE - Chun Li
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf03e ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz MLG FightStick TE
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf03f ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz FightStick SoulCaliber
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf042 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz FightStick TES+
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf080 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz FightStick TE2
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf501 ), k_eControllerType_XBox360Controller, NULL }, // HoriPad EX2 Turbo
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf502 ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro.VX SA
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf503 ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Stick VX
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf504 ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro. EX
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf505 ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Stick EX2B
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf506 ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro.EX Premium VLX
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf900 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Xbox 360 Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf901 ), k_eControllerType_XBox360Controller, NULL }, // Gamestop Xbox 360 Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf902 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Gamepad2
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf903 ), k_eControllerType_XBox360Controller, NULL }, // Tron Xbox 360 controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf904 ), k_eControllerType_XBox360Controller, NULL }, // PDP Versus Fighting Pad
{ MAKE_CONTROLLER_ID( 0x1bad, 0xf906 ), k_eControllerType_XBox360Controller, NULL }, // MortalKombat FightStick
{ MAKE_CONTROLLER_ID( 0x1bad, 0xfa01 ), k_eControllerType_XBox360Controller, NULL }, // MadCatz GamePad
{ MAKE_CONTROLLER_ID( 0x1bad, 0xfd00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza TE
{ MAKE_CONTROLLER_ID( 0x1bad, 0xfd01 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5000 ), k_eControllerType_XBox360Controller, NULL }, // Razer Atrox Arcade Stick
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5300 ), k_eControllerType_XBox360Controller, NULL }, // PowerA MINI PROEX Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5303 ), k_eControllerType_XBox360Controller, NULL }, // Xbox Airflo wired controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x530a ), k_eControllerType_XBox360Controller, NULL }, // Xbox 360 Pro EX Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x531a ), k_eControllerType_XBox360Controller, NULL }, // PowerA Pro Ex
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5397 ), k_eControllerType_XBox360Controller, NULL }, // FUS1ON Tournament Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5500 ), k_eControllerType_XBox360Controller, NULL }, // Hori XBOX 360 EX 2 with Turbo
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5501 ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro VX-SA
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5502 ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Stick VX Alt
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5503 ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Edge
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5506 ), k_eControllerType_XBox360Controller, NULL }, // Hori SOULCALIBUR V Stick
{ MAKE_CONTROLLER_ID( 0x24c6, 0x550d ), k_eControllerType_XBox360Controller, NULL }, // Hori GEM Xbox controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x550e ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro V Kai 360
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5508 ), k_eControllerType_XBox360Controller, NULL }, // Hori PAD A
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5510 ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Commander ONE
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b00 ), k_eControllerType_XBox360Controller, NULL }, // ThrustMaster Ferrari Italia 458 Racing Wheel
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b02 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster, Inc. GPX Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b03 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster Ferrari 458 Racing Wheel
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5d04 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafa ), k_eControllerType_XBox360Controller, NULL }, // Aplay Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafb ), k_eControllerType_XBox360Controller, NULL }, // Aplay Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafc ), k_eControllerType_XBox360Controller, NULL }, // Afterglow Gamepad 1
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafd ), k_eControllerType_XBox360Controller, NULL }, // Afterglow Gamepad 3
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller, NULL }, // Rock Candy Gamepad for Xbox 360
{ MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft X-Box One pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft X-Box One pad (Firmware 2015)
{ MAKE_CONTROLLER_ID( 0x045e, 0x02e0 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft X-Box One Elite pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with XBOXGIP driver on Windows
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b02 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b0a ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b0c ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (Bluetooth)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad (BLE)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b20 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (BLE)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b21 ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (BLE)
{ MAKE_CONTROLLER_ID( 0x045e, 0x0b22 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (BLE)
{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013a ), k_eControllerType_XBoxOneController, NULL }, // PDP Xbox One Controller (unlisted)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0145 ), k_eControllerType_XBoxOneController, "PDP MK X Fight Pad" }, // PDP MK X Fight Pad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0146 ), k_eControllerType_XBoxOneController, "PDP Xbox One Rock Candy" }, // PDP Rock Candy Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015b ), k_eControllerType_XBoxOneController, "PDP Fallout 4 Vault Boy Controller" }, // PDP Fallout 4 Vault Boy Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015c ), k_eControllerType_XBoxOneController, "PDP Xbox One @Play Controller" }, // PDP @Play Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015d ), k_eControllerType_XBoxOneController, "PDP Mirror's Edge Controller" }, // PDP Mirror's Edge Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015f ), k_eControllerType_XBoxOneController, "PDP Metallic Controller" }, // PDP Metallic Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0160 ), k_eControllerType_XBoxOneController, "PDP NFL Face-Off Controller" }, // PDP NFL Official Face-Off Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0161 ), k_eControllerType_XBoxOneController, "PDP Xbox One Camo" }, // PDP Camo Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0162 ), k_eControllerType_XBoxOneController, "PDP Xbox One Controller" }, // PDP Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0163 ), k_eControllerType_XBoxOneController, "PDP Deliverer of Truth" }, // PDP Legendary Collection: Deliverer of Truth
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0164 ), k_eControllerType_XBoxOneController, "PDP Battlefield 1 Controller" }, // PDP Battlefield 1 Official Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0165 ), k_eControllerType_XBoxOneController, "PDP Titanfall 2 Controller" }, // PDP Titanfall 2 Official Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0166 ), k_eControllerType_XBoxOneController, "PDP Mass Effect: Andromeda Controller" }, // PDP Mass Effect: Andromeda Official Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0167 ), k_eControllerType_XBoxOneController, "PDP Halo Wars 2 Face-Off Controller" }, // PDP Halo Wars 2 Official Face-Off Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0205 ), k_eControllerType_XBoxOneController, "PDP Victrix Pro Fight Stick" }, // PDP Victrix Pro Fight Stick
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0206 ), k_eControllerType_XBoxOneController, "PDP Mortal Kombat Controller" }, // PDP Mortal Kombat 25 Anniversary Edition Stick (Xbox One)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0246 ), k_eControllerType_XBoxOneController, "PDP Xbox One Rock Candy" }, // PDP Rock Candy Wired Controller for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0261 ), k_eControllerType_XBoxOneController, "PDP Xbox One Camo" }, // PDP Camo Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0262 ), k_eControllerType_XBoxOneController, "PDP Xbox One Controller" }, // PDP Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a0 ), k_eControllerType_XBoxOneController, "PDP Xbox One Midnight Blue" }, // PDP Wired Controller for Xbox One - Midnight Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a1 ), k_eControllerType_XBoxOneController, "PDP Xbox One Verdant Green" }, // PDP Wired Controller for Xbox One - Verdant Green
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a2 ), k_eControllerType_XBoxOneController, "PDP Xbox One Crimson Red" }, // PDP Wired Controller for Xbox One - Crimson Red
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a3 ), k_eControllerType_XBoxOneController, "PDP Xbox One Arctic White" }, // PDP Wired Controller for Xbox One - Arctic White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a4 ), k_eControllerType_XBoxOneController, "PDP Xbox One Phantom Black" }, // PDP Wired Controller for Xbox One - Stealth Series | Phantom Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Ghost White" }, // PDP Wired Controller for Xbox One - Stealth Series | Ghost White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a6 ), k_eControllerType_XBoxOneController, "PDP Xbox One Revenant Blue" }, // PDP Wired Controller for Xbox One - Stealth Series | Revenant Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a7 ), k_eControllerType_XBoxOneController, "PDP Xbox One Raven Black" }, // PDP Wired Controller for Xbox One - Raven Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a8 ), k_eControllerType_XBoxOneController, "PDP Xbox One Arctic White" }, // PDP Wired Controller for Xbox One - Arctic White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a9 ), k_eControllerType_XBoxOneController, "PDP Xbox One Midnight Blue" }, // PDP Wired Controller for Xbox One - Midnight Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02aa ), k_eControllerType_XBoxOneController, "PDP Xbox One Verdant Green" }, // PDP Wired Controller for Xbox One - Verdant Green
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ab ), k_eControllerType_XBoxOneController, "PDP Xbox One Crimson Red" }, // PDP Wired Controller for Xbox One - Crimson Red
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ac ), k_eControllerType_XBoxOneController, "PDP Xbox One Ember Orange" }, // PDP Wired Controller for Xbox One - Ember Orange
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ad ), k_eControllerType_XBoxOneController, "PDP Xbox One Phantom Black" }, // PDP Wired Controller for Xbox One - Stealth Series | Phantom Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ae ), k_eControllerType_XBoxOneController, "PDP Xbox One Ghost White" }, // PDP Wired Controller for Xbox One - Stealth Series | Ghost White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02af ), k_eControllerType_XBoxOneController, "PDP Xbox One Revenant Blue" }, // PDP Wired Controller for Xbox One - Stealth Series | Revenant Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02b0 ), k_eControllerType_XBoxOneController, "PDP Xbox One Raven Black" }, // PDP Wired Controller for Xbox One - Raven Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02b1 ), k_eControllerType_XBoxOneController, "PDP Xbox One Arctic White" }, // PDP Wired Controller for Xbox One - Arctic White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02b3 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Prismatic Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02b5 ), k_eControllerType_XBoxOneController, "PDP Xbox One GAMEware Controller" }, // PDP GAMEware Wired Controller Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02b6 ), k_eControllerType_XBoxOneController, NULL }, // PDP One-Handed Joystick Adaptive Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02bd ), k_eControllerType_XBoxOneController, "PDP Xbox One Royal Purple" }, // PDP Wired Controller for Xbox One - Royal Purple
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02be ), k_eControllerType_XBoxOneController, "PDP Xbox One Raven Black" }, // PDP Deluxe Wired Controller for Xbox One - Raven Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02bf ), k_eControllerType_XBoxOneController, "PDP Xbox One Midnight Blue" }, // PDP Deluxe Wired Controller for Xbox One - Midnight Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c0 ), k_eControllerType_XBoxOneController, "PDP Xbox One Phantom Black" }, // PDP Deluxe Wired Controller for Xbox One - Stealth Series | Phantom Black
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c1 ), k_eControllerType_XBoxOneController, "PDP Xbox One Ghost White" }, // PDP Deluxe Wired Controller for Xbox One - Stealth Series | Ghost White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c2 ), k_eControllerType_XBoxOneController, "PDP Xbox One Revenant Blue" }, // PDP Deluxe Wired Controller for Xbox One - Stealth Series | Revenant Blue
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c3 ), k_eControllerType_XBoxOneController, "PDP Xbox One Verdant Green" }, // PDP Deluxe Wired Controller for Xbox One - Verdant Green
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c4 ), k_eControllerType_XBoxOneController, "PDP Xbox One Ember Orange" }, // PDP Deluxe Wired Controller for Xbox One - Ember Orange
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Royal Purple" }, // PDP Deluxe Wired Controller for Xbox One - Royal Purple
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c6 ), k_eControllerType_XBoxOneController, "PDP Xbox One Crimson Red" }, // PDP Deluxe Wired Controller for Xbox One - Crimson Red
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c7 ), k_eControllerType_XBoxOneController, "PDP Xbox One Arctic White" }, // PDP Deluxe Wired Controller for Xbox One - Arctic White
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c8 ), k_eControllerType_XBoxOneController, "PDP Kingdom Hearts Controller" }, // PDP Kingdom Hearts Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02c9 ), k_eControllerType_XBoxOneController, "PDP Xbox One Phantasm Red" }, // PDP Deluxe Wired Controller for Xbox One - Stealth Series | Phantasm Red
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ca ), k_eControllerType_XBoxOneController, "PDP Xbox One Specter Violet" }, // PDP Deluxe Wired Controller for Xbox One - Stealth Series | Specter Violet
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02cb ), k_eControllerType_XBoxOneController, "PDP Xbox One Specter Violet" }, // PDP Wired Controller for Xbox One - Stealth Series | Specter Violet
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02cd ), k_eControllerType_XBoxOneController, "PDP Xbox One Blu-merang" }, // PDP Rock Candy Wired Controller for Xbox One - Blu-merang
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ce ), k_eControllerType_XBoxOneController, "PDP Xbox One Cranblast" }, // PDP Rock Candy Wired Controller for Xbox One - Cranblast
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02cf ), k_eControllerType_XBoxOneController, "PDP Xbox One Aqualime" }, // PDP Rock Candy Wired Controller for Xbox One - Aqualime
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Red Camo" }, // PDP Wired Controller for Xbox One - Red Camo
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0446 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02da ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Afterglow" }, // PDP Xbox Series X Afterglow
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d6 ), k_eControllerType_XBoxOneController, "Victrix Gambit Tournament Controller" }, // Victrix Gambit Tournament Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02d9 ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Midnight Blue" }, // PDP Xbox Series X Midnight Blue
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro Hayabusa (USA) Xbox One
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController, NULL }, // HORIPAD ONE
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro V Kai Xbox One
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00c5 ), k_eControllerType_XBoxOneController, NULL }, // HORI Fighting Commander
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController, NULL }, // Razer Atrox Arcade Stick
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wildcat
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a14 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Ultimate
{ MAKE_CONTROLLER_ID( 0x1532, 0x0a15 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Tournament Edition
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Black Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2002 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Gray/White Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2003 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Green Inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2004 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Pink inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2005 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - Black
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2006 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - White
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2009 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Red inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Blue inline
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200b ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Red
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200c ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Blue
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200d ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Seafoam Fade
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200e ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Midnight Blue
{ MAKE_CONTROLLER_ID( 0x20d6, 0x200f ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Soldier Green
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2011 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired - Metallic Ice
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2012 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Cuphead EnWired Controller - Mugman
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2015 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Blue Hint
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2016 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Green Hint
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2017 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Cntroller - Arctic Camo
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2018 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Arc Lightning
{ MAKE_CONTROLLER_ID( 0x20d6, 0x2019 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Royal Purple
{ MAKE_CONTROLLER_ID( 0x20d6, 0x201a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Nebula
{ MAKE_CONTROLLER_ID( 0x20d6, 0x4001 ), k_eControllerType_XBoxOneController, "PowerA Fusion Pro 2 Controller" }, // PowerA Fusion Pro 2 Wired Controller (Xbox Series X style)
{ MAKE_CONTROLLER_ID( 0x20d6, 0x4002 ), k_eControllerType_XBoxOneController, "PowerA Spectra Infinity Controller" }, // PowerA Spectra Infinity Wired Controller (Xbox Series X style)
{ MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Xbox One Mini Wired Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController, NULL }, // Xbox ONE spectra
{ MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA Xbox One Controller" }, // PowerA Xbox ONE liquid metal controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x551a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Pro Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x561a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x581a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Classic Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x591a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Pro Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x592a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Spectra Pro
{ MAKE_CONTROLLER_ID( 0x24c6, 0x791a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x2e24, 0x0652 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke
{ MAKE_CONTROLLER_ID( 0x2e24, 0x1618 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke
{ MAKE_CONTROLLER_ID( 0x2e24, 0x1688 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin X91
{ MAKE_CONTROLLER_ID( 0x146b, 0x0611 ), k_eControllerType_XBoxOneController, NULL }, // Xbox Controller Mode for NACON Revolution 3
// These have been added via Minidump for unrecognized Xinput controller assert
{ MAKE_CONTROLLER_ID( 0x0000, 0x0000 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x045e, 0x02a2 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller - Microsoft VID
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1414 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0159 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0xfaff ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006d ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a4 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x1832 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x187f ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x1883 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x03eb, 0xff01 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2303 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef8 ), k_eControllerType_XBox360Controller, NULL }, // Homemade fightstick based on brook pcb (with XInput driver??)
{ MAKE_CONTROLLER_ID( 0x046d, 0x1000 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1345, 0x6006 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x056e, 0x2012 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x146b, 0x0602 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ae ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x046d, 0x0401 ), k_eControllerType_XBox360Controller, NULL }, // logitech xinput
{ MAKE_CONTROLLER_ID( 0x046d, 0x0301 ), k_eControllerType_XBox360Controller, NULL }, // logitech xinput
{ MAKE_CONTROLLER_ID( 0x046d, 0xcaa3 ), k_eControllerType_XBox360Controller, NULL }, // logitech xinput
{ MAKE_CONTROLLER_ID( 0x046d, 0xc261 ), k_eControllerType_XBox360Controller, NULL }, // logitech xinput
{ MAKE_CONTROLLER_ID( 0x046d, 0x0291 ), k_eControllerType_XBox360Controller, NULL }, // logitech xinput
{ MAKE_CONTROLLER_ID( 0x0079, 0x18d3 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00b1 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0001, 0x0001 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x188e ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x187c ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x189c ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x0079, 0x1874 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x0050 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x2e ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x9886, 0x24 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x91 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1430, 0x719 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xf0d, 0xed ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xf0d, 0xc0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x152 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a7 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x1007 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2b8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2503 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x79, 0x18a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
/* Added from Minidumps 10-9-19 */
{ MAKE_CONTROLLER_ID( 0x0, 0x6686 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x11ff, 0x511 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x12ab, 0x304 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1430, 0x291 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1430, 0x2a9 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1430, 0x70b ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x146b, 0x604 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x146b, 0x605 ), k_eControllerType_XBoxOneController, NULL }, // NACON PS4 controller in Xbox mode - might also be other bigben brand xbox controllers
{ MAKE_CONTROLLER_ID( 0x146b, 0x606 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x146b, 0x609 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0x28e ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0x2a0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x1bad, 0x5500 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x20ab, 0x55ef ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x24c6, 0x5509 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2516, 0x69 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x25b1, 0x360 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2203 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x11 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x53 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0xb7 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x1004 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0x1008 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x46d, 0xf301 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x738, 0x2a0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x738, 0x7263 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x738, 0xb738 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x738, 0xcb29 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x738, 0xf401 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x79, 0x18c2 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x79, 0x18c8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x79, 0x18cf ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xc12, 0xe17 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xc12, 0xe1c ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xc12, 0xe22 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xc12, 0xe30 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xd2d2, 0xd2d2 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xd62, 0x9a1a ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xd62, 0x9a1b ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe00, 0xe00 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x12a ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a2 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a5 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2b2 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2bd ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2bf ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2c0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0x2c6 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xf0d, 0x97 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xf0d, 0xba ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xf0d, 0xd8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xfff, 0x2a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x45e, 0x867 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
// Added 12-17-2020
{ MAKE_CONTROLLER_ID( 0x16d0, 0xf3f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x2f24, 0x8f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0xe6f, 0xf501 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller
//{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/, NULL }, // Unknown Controller
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController, NULL }, // MFI Extended Gamepad (generic entry for iOS/tvOS)
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController, NULL }, // MFI Standard Gamepad (generic entry for iOS/tvOS)
// We now support Joy-Cons if SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS is set to "1", but they won't be combined into one controller.
{ MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left)
{ MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right)
// This same controller ID is spoofed by many 3rd-party Switch controllers.
// The ones we currently know of are:
// * Any 8bitdo controller with Switch support
// * ORTZ Gaming Wireless Pro Controller
// * ZhiXu Gamepad Wireless
// * Sunwaytek Wireless Motion Controller for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch Pro Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORIPAD for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Pokken Tournament DX Pro Pad
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00f6 ), k_eControllerType_SwitchProController, NULL }, // HORI Wireless Switch Pad
#ifdef _WIN32
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_XInputSwitchController, NULL }, // HORI Fighting Commander - Is a Switch controller but shows up through XInput on Windows.
#else
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_SwitchProController, "HORI Fighting Commander" },
#endif
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0180 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Pro Controller for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0181 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Deluxe Wired Pro Controller for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0184 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Deluxe+ Audio Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB is for charging only. Many later "Wireless" line devices w/ gyro also use this vid/pid
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0187 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Rockcandy Wired Controller
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0188 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Afterglow Wired Deluxe+ Audio Controller
{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Fight Pad
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Super Mario Controller
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa714 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Spectra Controller
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa715 ), k_eControllerType_SwitchInputOnlyController, NULL }, // Power A Fusion Wireless Arcade Stick (USB Mode) Over BT is shows up as 057e 2009
{ MAKE_CONTROLLER_ID( 0x20d6, 0xa716 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Pro Controller - USB requires toggling switch on back of device
// Valve products
{ MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch, NULL }, // Streaming mobile touch virtual controls
{ MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController, NULL }, // Valve Legacy Steam Controller (CHELL)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController, NULL }, // Valve wired Steam Controller (D0G)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1105 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1106 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1142 ), k_eControllerType_SteamController, NULL }, // Valve wireless Steam Controller
{ MAKE_CONTROLLER_ID( 0x28de, 0x1201 ), k_eControllerType_SteamControllerV2, NULL }, // Valve wired Steam Controller (HEADCRAB)
{ MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2, NULL }, // Valve Bluetooth Steam Controller (HEADCRAB)
};
static SDL_INLINE const char *GetControllerTypeOverride( int nVID, int nPID )
{
const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERTYPE);
if (hint) {
char key[32];
const char *spot = NULL;
SDL_snprintf(key, sizeof(key), "0x%.4x/0x%.4x=", nVID, nPID);
spot = SDL_strstr(hint, key);
if (!spot) {
SDL_snprintf(key, sizeof(key), "0x%.4X/0x%.4X=", nVID, nPID);
spot = SDL_strstr(hint, key);
}
if (spot) {
spot += SDL_strlen(key);
if (SDL_strncmp(spot, "k_eControllerType_", 18) == 0) {
spot += 18;
}
return spot;
}
}
return NULL;
}
static SDL_INLINE EControllerType GuessControllerType( int nVID, int nPID )
{
#if 0//def _DEBUG
// Verify that there are no duplicates in the controller list
// If the list were sorted, we could do this much more efficiently, as well as improve lookup speed.
static bool s_bCheckedForDuplicates;
if ( !s_bCheckedForDuplicates )
{
s_bCheckedForDuplicates = true;
int i, j;
for ( i = 0; i < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++i )
{
for ( j = i + 1; j < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++j )
{
if ( arrControllers[ i ].m_unDeviceID == arrControllers[ j ].m_unDeviceID )
{
Log( "Duplicate controller entry found for VID 0x%.4x PID 0x%.4x\n", ( arrControllers[ i ].m_unDeviceID >> 16 ), arrControllers[ i ].m_unDeviceID & 0xFFFF );
}
}
}
}
#endif // _DEBUG
unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
int iIndex;
const char *pszOverride = GetControllerTypeOverride( nVID, nPID );
if ( pszOverride )
{
if ( SDL_strncasecmp( pszOverride, "Xbox360", 7 ) == 0 )
{
return k_eControllerType_XBox360Controller;
}
if ( SDL_strncasecmp( pszOverride, "XboxOne", 7 ) == 0 )
{
return k_eControllerType_XBoxOneController;
}
if ( SDL_strncasecmp( pszOverride, "PS3", 3 ) == 0 )
{
return k_eControllerType_PS3Controller;
}
if ( SDL_strncasecmp( pszOverride, "PS4", 3 ) == 0 )
{
return k_eControllerType_PS4Controller;
}
if ( SDL_strncasecmp( pszOverride, "PS5", 3 ) == 0 )
{
return k_eControllerType_PS5Controller;
}
if ( SDL_strncasecmp( pszOverride, "SwitchPro", 9 ) == 0 )
{
return k_eControllerType_SwitchProController;
}
if ( SDL_strncasecmp( pszOverride, "Steam", 5 ) == 0 )
{
return k_eControllerType_SteamController;
}
return k_eControllerType_UnknownNonSteamController;
}
for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )
{
if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID )
{
return arrControllers[ iIndex ].m_eControllerType;
}
}
return k_eControllerType_UnknownNonSteamController;
}
static SDL_INLINE const char *GuessControllerName( int nVID, int nPID )
{
unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
int iIndex;
for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )
{
if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID )
{
return arrControllers[ iIndex ].m_pszName;
}
}
return NULL;
}
#undef MAKE_CONTROLLER_ID
static SDL_INLINE int GetDefaultDeadzoneSizeForControllerType( EControllerType eControllerType )
{
switch ( eControllerType )
{
case k_eControllerType_UnknownNonSteamController:
case k_eControllerType_XBoxOneController:
case k_eControllerType_XBox360Controller:
case k_eControllerType_AppleController:
case k_eControllerType_AndroidController:
case k_eControllerType_PS3Controller:
case k_eControllerType_PS5Controller:
return 10000;
case k_eControllerType_SteamControllerV2:
return 8192;
case k_eControllerType_PS4Controller:
return 4096;
case k_eControllerType_SwitchJoyConLeft:
case k_eControllerType_SwitchJoyConRight:
case k_eControllerType_SwitchJoyConPair:
return 8192; // Actual dead-zone should be 15% of full-scale, but we use this to account for variances in 3rd-party controllers
case k_eControllerType_SwitchProController:
return 8192; // Actual dead-zone should be closer to 10% of full-scale, but we use this to account for variances in 3rd-party controllers
default:
return 8192;
}
}
#endif // CONSTANTS_H
/* vi: set ts=4 sw=4 noexpandtab: */

View File

@@ -744,6 +744,7 @@ DARWIN_JoystickDetect(void)
}
}
/* Function to get the device-dependent name of a joystick */
const char *
DARWIN_JoystickGetDeviceName(int device_index)
{
@@ -751,12 +752,6 @@ DARWIN_JoystickGetDeviceName(int device_index)
return device ? device->product : "UNKNOWN";
}
const char *
DARWIN_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
DARWIN_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -1120,7 +1115,6 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickGetCount,
DARWIN_JoystickDetect,
DARWIN_JoystickGetDeviceName,
DARWIN_JoystickGetDevicePath,
DARWIN_JoystickGetDevicePlayerIndex,
DARWIN_JoystickSetDevicePlayerIndex,
DARWIN_JoystickGetDeviceGUID,

View File

@@ -52,12 +52,6 @@ DUMMY_JoystickGetDeviceName(int device_index)
return NULL;
}
static const char *
DUMMY_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
DUMMY_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -152,7 +146,6 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickGetCount,
DUMMY_JoystickDetect,
DUMMY_JoystickGetDeviceName,
DUMMY_JoystickGetDevicePath,
DUMMY_JoystickGetDevicePlayerIndex,
DUMMY_JoystickSetDevicePlayerIndex,
DUMMY_JoystickGetDeviceGUID,

View File

@@ -280,12 +280,6 @@ EMSCRIPTEN_JoystickGetDeviceName(int device_index)
return JoystickByDeviceIndex(device_index)->name;
}
static const char *
EMSCRIPTEN_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -450,7 +444,6 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
EMSCRIPTEN_JoystickGetCount,
EMSCRIPTEN_JoystickDetect,
EMSCRIPTEN_JoystickGetDeviceName,
EMSCRIPTEN_JoystickGetDevicePath,
EMSCRIPTEN_JoystickGetDevicePlayerIndex,
EMSCRIPTEN_JoystickSetDevicePlayerIndex,
EMSCRIPTEN_JoystickGetDeviceGUID,

View File

@@ -64,15 +64,15 @@ extern "C"
char name[B_OS_NAME_LENGTH];
/* Search for attached joysticks */
nports = joystick.CountDevices();
numjoysticks = 0;
SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
nports = joystick.CountDevices();
numjoysticks = 0;
SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport));
SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname));
for (i = 0; (numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i)
{
if (joystick.GetDeviceName(i, name) == B_OK) {
if (joystick.Open(name) != B_ERROR) {
BString stick_name;
BString stick_name;
joystick.GetControllerName(&stick_name);
SDL_joyport[numjoysticks] = SDL_strdup(name);
SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String());
@@ -93,16 +93,12 @@ extern "C"
{
}
/* Function to get the device-dependent name of a joystick */
static const char *HAIKU_JoystickGetDeviceName(int device_index)
{
return SDL_joyname[device_index];
}
static const char *HAIKU_JoystickGetDevicePath(int device_index)
{
return SDL_joyport[device_index];
}
static int HAIKU_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
@@ -302,7 +298,6 @@ extern "C"
HAIKU_JoystickGetCount,
HAIKU_JoystickDetect,
HAIKU_JoystickGetDeviceName,
HAIKU_JoystickGetDevicePath,
HAIKU_JoystickGetDevicePlayerIndex,
HAIKU_JoystickSetDevicePlayerIndex,
HAIKU_JoystickGetDeviceGUID,

View File

@@ -53,7 +53,6 @@ typedef struct {
/* Without this variable, hid_write starts to lag a TON */
SDL_bool rumbleUpdate;
SDL_bool m_bUseButtonLabels;
SDL_bool useRumbleBrake;
} SDL_DriverGameCube_Context;
static SDL_bool
@@ -71,7 +70,7 @@ HIDAPI_DriverGameCube_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverGameCube_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverGameCube_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Nintendo GameCube Controller";
}
@@ -93,14 +92,6 @@ static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata,
ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE);
}
static void SDLCALL SDL_JoystickGameCubeRumbleBrakeHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
if (hint) {
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata;
ctx->useRumbleBrake = SDL_GetStringBoolean(hint, SDL_FALSE);
}
}
static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button)
{
if (!ctx->m_bUseButtonLabels) {
@@ -151,7 +142,6 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
ctx->joysticks[2] = -1;
ctx->joysticks[3] = -1;
ctx->rumble[0] = rumbleMagic;
ctx->useRumbleBrake = SDL_FALSE;
if (device->vendor_id != USB_VENDOR_NINTENDO) {
ctx->pc_mode = SDL_TRUE;
@@ -205,8 +195,6 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
}
}
SDL_AddHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
@@ -451,22 +439,12 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
if (joystick->instance_id == ctx->joysticks[i]) {
if (ctx->wireless[i]) {
return SDL_SetError("Nintendo GameCube WaveBird controllers do not support rumble");
return SDL_SetError("Ninteno GameCube WaveBird controllers do not support rumble");
}
if (!ctx->rumbleAllowed[i]) {
return SDL_SetError("Second USB cable for WUP-028 not connected");
}
if (ctx->useRumbleBrake) {
if (low_frequency_rumble == 0 && high_frequency_rumble > 0) {
val = 0; /* if only low is 0 we want to do a regular stop*/
} else if (low_frequency_rumble == 0 && high_frequency_rumble == 0) {
val = 2; /* if both frequencies are 0 we want to do a hard stop */
} else {
val = 1; /* normal rumble */
}
} else {
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
}
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
if (val != ctx->rumble[i + 1]) {
ctx->rumble[i + 1] = val;
ctx->rumbleUpdate = SDL_TRUE;
@@ -476,7 +454,8 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
}
/* Should never get here! */
return SDL_SetError("Couldn't find joystick");
SDL_SetError("Couldn't find joystick");
return -1;
}
static int
@@ -544,8 +523,6 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_LockMutex(device->dev_lock);
{

View File

@@ -54,7 +54,7 @@ HIDAPI_DriverLuna_IsSupportedDevice(const char *name, SDL_GameControllerType typ
}
static const char *
HIDAPI_DriverLuna_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverLuna_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Amazon Luna Controller";
}
@@ -267,16 +267,16 @@ HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverL
/* Battery level report */
int level = data[1] * 100 / 0xFF;
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
}
else if (level <= 20) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
}
else if (level <= 70) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
}
else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
return;

View File

@@ -155,7 +155,7 @@ HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type
}
static const char *
HIDAPI_DriverPS4_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_SONY) {
return "PS4 Controller";
@@ -177,12 +177,6 @@ static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id)
(product_id == USB_PRODUCT_RAZER_PANTHERA || product_id == USB_PRODUCT_RAZER_PANTHERA_EVO)) {
return SDL_FALSE;
}
/* The Victrix Pro FS v2 will hang on reboot if we send output reports */
if (vendor_id == USB_VENDOR_PDP && product_id == USB_PRODUCT_VICTRIX_FS_PRO_V2) {
return SDL_FALSE;
}
return SDL_TRUE;
}
@@ -801,18 +795,18 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
if (packet->ucBatteryLevel & 0x10) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
} else {
/* Battery level ranges from 0 to 10 */
int level = (packet->ucBatteryLevel & 0xF);
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (level <= 2) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (level <= 7) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -59,7 +59,6 @@ typedef enum
{
k_EPS5FeatureReportIdCalibration = 0x05,
k_EPS5FeatureReportIdSerialNumber = 0x09,
k_EPS5FeatureReportIdFirmwareInfo = 0x20,
} EPS5FeatureReportId;
typedef struct
@@ -185,7 +184,7 @@ HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type
}
static const char *
HIDAPI_DriverPS5_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_SONY) {
return "PS5 Controller";
@@ -602,13 +601,6 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
data[6], data[5], data[4], data[3], data[2], data[1]);
joystick->serial = SDL_strdup(serial);
}
/* Read the firmware version
This will also enable enhanced reports over Bluetooth
*/
if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdFirmwareInfo, data, USB_PACKET_LENGTH) >= 46) {
joystick->firmware_version = (Uint16)data[44] | ((Uint16)data[45] << 8);
}
}
if (!joystick->serial && device->serial && SDL_strlen(device->serial) == 12) {
@@ -755,11 +747,7 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
}
}
if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) {
return -1;
}
return 0;
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
}
static int
@@ -969,10 +957,7 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
axis = ((int)packet->ucRightJoystickY * 257) - 32768;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
/* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't
* seem to always work. Possibly related to being 100% charged?
*/
if (!ctx->is_bluetooth) {
if (packet->ucBatteryLevel & 0x10) {
/* 0x20 set means fully charged */
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
} else {

View File

@@ -53,7 +53,7 @@ typedef struct SDL_HIDAPI_RumbleContext
static SDL_HIDAPI_RumbleContext rumble_context;
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
static int SDL_HIDAPI_RumbleThread(void *data)
{
SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;

View File

@@ -55,7 +55,7 @@ HIDAPI_DriverStadia_IsSupportedDevice(const char *name, SDL_GameControllerType t
}
static const char *
HIDAPI_DriverStadia_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverStadia_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Google Stadia Controller";
}

View File

@@ -1004,7 +1004,7 @@ HIDAPI_DriverSteam_IsSupportedDevice(const char *name, SDL_GameControllerType ty
}
static const char *
HIDAPI_DriverSteam_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverSteam_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Steam Controller";
}

View File

@@ -63,11 +63,6 @@
#define SWITCH_GYRO_SCALE 14.2842f
#define SWITCH_ACCEL_SCALE 4096.f
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
#define SWITCH_GYRO_SCALE_MULT 936.0f
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
#define SWITCH_ACCEL_SCALE_MULT 4.0f
typedef enum {
k_eSwitchInputReportIDs_SubcommandReply = 0x21,
k_eSwitchInputReportIDs_FullControllerState = 0x30,
@@ -119,14 +114,6 @@ typedef enum {
#define k_unSPIStickCalibrationEndOffset 0x604E
#define k_unSPIStickCalibrationLength (k_unSPIStickCalibrationEndOffset - k_unSPIStickCalibrationStartOffset + 1)
#define k_unSPIIMUScaleStartOffset 0x6020
#define k_unSPIIMUScaleEndOffset 0x6037
#define k_unSPIIMUScaleLength (k_unSPIIMUScaleEndOffset - k_unSPIIMUScaleStartOffset + 1)
#define k_unSPIIMUUserScaleStartOffset 0x8026
#define k_unSPIIMUUserScaleEndOffset 0x8039
#define k_unSPIIMUUserScaleLength (k_unSPIIMUUserScaleEndOffset - k_unSPIIMUUserScaleStartOffset + 1)
#pragma pack(1)
typedef struct
{
@@ -279,16 +266,6 @@ typedef struct {
Sint16 sMax;
} axis[2];
} m_StickExtents[2];
struct IMUScaleData {
float fAccelScaleX;
float fAccelScaleY;
float fAccelScaleZ;
float fGyroScaleX;
float fGyroScaleY;
float fGyroScaleZ;
} m_IMUScaleData;
} SDL_DriverSwitch_Context;
@@ -305,29 +282,9 @@ HasHomeLED(int vendor_id, int product_id)
return SDL_FALSE;
}
/* The Nintendo Online classic controllers don't have a Home LED */
if (vendor_id == USB_VENDOR_NINTENDO &&
(product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER)) {
return SDL_FALSE;
}
return SDL_TRUE;
}
static SDL_bool
AlwaysUsesLabels(int vendor_id, int product_id)
{
/* These controllers don't have a diamond button configuration, so always use labels */
if (vendor_id == USB_VENDOR_NINTENDO &&
(product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER)) {
return SDL_TRUE;
}
return SDL_FALSE;
}
static SDL_bool
IsGameCubeFormFactor(int vendor_id, int product_id)
{
@@ -362,7 +319,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t
}
static const char *
HIDAPI_DriverSwitch_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
/* Give a user friendly name for this controller */
if (vendor_id == USB_VENDOR_NINTENDO) {
@@ -375,24 +332,8 @@ HIDAPI_DriverSwitch_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 pro
}
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) {
/* Use the given name for the Nintendo Online NES Controllers */
if (SDL_strncmp(name, "NES Controller", 14) == 0) {
return name;
}
return "Nintendo Switch Joy-Con Right";
}
if (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) {
return "Nintendo N64 Controller";
}
if (product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) {
return "Nintendo SEGA Genesis Controller";
}
if (product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) {
return "Nintendo SNES Controller";
}
}
return "Nintendo Switch Pro Controller";
@@ -828,72 +769,6 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_
return SDL_TRUE;
}
static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context* ctx)
{
Uint8* pIMUScale;
SwitchSubcommandInputPacket_t* reply = NULL;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
/* Read Calibration Info */
SwitchSPIOpData_t readParams;
readParams.unAddress = k_unSPIIMUScaleStartOffset;
readParams.ucLength = k_unSPIIMUScaleLength;
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply)) {
const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE;
const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE;
ctx->m_IMUScaleData.fAccelScaleX = accelScale;
ctx->m_IMUScaleData.fAccelScaleY = accelScale;
ctx->m_IMUScaleData.fAccelScaleZ = accelScale;
ctx->m_IMUScaleData.fGyroScaleX = gyroScale;
ctx->m_IMUScaleData.fGyroScaleY = gyroScale;
ctx->m_IMUScaleData.fGyroScaleZ = gyroScale;
return SDL_FALSE;
}
/* IMU scale gives us multipliers for converting raw values to real world values */
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = ((pIMUScale[1] << 8) & 0xF00) | pIMUScale[0];
sAccelRawY = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
sAccelRawZ = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
sGyroRawX = ((pIMUScale[13] << 8) & 0xF00) | pIMUScale[12];
sGyroRawY = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
sGyroRawZ = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) {
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
sAccelRawY = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
sAccelRawZ = ((pIMUScale[7] << 8) & 0xF00) | pIMUScale[6];
sGyroRawX = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
sGyroRawY = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
sGyroRawZ = ((pIMUScale[19] << 8) & 0xF00) | pIMUScale[18];
}
/* Accelerometer scale */
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
/* Gyro scale */
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
return SDL_TRUE;
}
static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue, Sint16 sCenter)
{
sRawValue -= sCenter;
@@ -1039,11 +914,6 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
goto error;
}
if (!LoadIMUCalibration(ctx)) {
SDL_SetError("Couldn't load sensor calibration");
goto error;
}
if (!SetVibrationEnabled(ctx, 1)) {
SDL_SetError("Couldn't enable vibration");
goto error;
@@ -1097,12 +967,8 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
ctx->m_bIsGameCube = SDL_TRUE;
}
if (AlwaysUsesLabels(device->vendor_id, device->product_id)) {
ctx->m_bUseButtonLabels = SDL_TRUE;
} else {
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
}
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
/* Initialize the joystick capabilities */
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
@@ -1157,7 +1023,8 @@ HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16
ctx->m_bRumbleActive = (low_frequency_rumble || high_frequency_rumble) ? SDL_TRUE : SDL_FALSE;
if (!WriteRumble(ctx)) {
return SDL_SetError("Couldn't send rumble packet");
SDL_SetError("Couldn't send rumble packet");
return -1;
}
return 0;
}
@@ -1280,6 +1147,20 @@ HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joy
return 0;
}
static float
HIDAPI_DriverSwitch_ScaleGyro(Sint16 value)
{
float result = (value / SWITCH_GYRO_SCALE) * (float)M_PI / 180.0f;
return result;
}
static float
HIDAPI_DriverSwitch_ScaleAccel(Sint16 value)
{
float result = (value / SWITCH_ACCEL_SCALE) * SDL_STANDARD_GRAVITY;
return result;
}
static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet)
{
Sint16 axis;
@@ -1477,13 +1358,13 @@ static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *c
* users will want consistent axis mappings across devices.
*/
if (type == SDL_SENSOR_GYRO) {
data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]);
data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2];
data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]);
data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]);
} else {
data[0] = -(ctx->m_IMUScaleData.fAccelScaleY * (float)values[1]);
data[1] = ctx->m_IMUScaleData.fAccelScaleZ * (float)values[2];
data[2] = -(ctx->m_IMUScaleData.fAccelScaleX * (float)values[0]);
data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]);
}
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
@@ -1560,20 +1441,20 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
* LSB of connection nibble is USB/Switch connection status
*/
if (packet->controllerState.ucBatteryAndConnection & 0x1) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
} else {
/* LSB of the battery nibble is used to report charging.
* The battery level is reported from 0(empty)-8(full)
*/
int level = (packet->controllerState.ucBatteryAndConnection & 0xE0) >> 4;
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (level <= 2) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (level <= 6) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -83,7 +83,7 @@ HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXbox360_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return NULL;
}

View File

@@ -57,7 +57,7 @@ HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXbox360W_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Xbox 360 Wireless Controller";
}
@@ -81,13 +81,13 @@ UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level)
float normalized_level = (float)level / 255.0f;
if (normalized_level <= 0.05f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (normalized_level <= 0.20f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (normalized_level <= 0.70f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -285,7 +285,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXboxOne_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return NULL;
}
@@ -478,6 +478,30 @@ HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Jo
return SDL_Unsupported();
}
static Sint16 FilterLeftThumb(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && axis >= -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
return 0;
}
return axis;
}
static Sint16 FilterRightThumb(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && axis >= -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
return 0;
}
return axis;
}
static Sint16 FilterTrigger(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD) {
return 0;
}
return axis;
}
static void
HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
{
@@ -612,7 +636,7 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
if (axis == -32768 && size == 30 && (data[22] & 0x80) != 0) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, FilterTrigger(axis));
axis = ((int)*(Sint16*)(&data[8]) * 64) - 32768;
if (axis == -32768 && size == 30 && (data[22] & 0x40) != 0) {
@@ -621,16 +645,16 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, FilterTrigger(axis));
axis = *(Sint16*)(&data[10]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, FilterLeftThumb(axis));
axis = *(Sint16*)(&data[12]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, FilterLeftThumb(~axis));
axis = *(Sint16*)(&data[14]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, FilterRightThumb(axis));
axis = *(Sint16*)(&data[16]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, FilterRightThumb(~axis));
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
@@ -830,22 +854,22 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, FilterTrigger(axis));
axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, FilterTrigger(axis));
axis = (int)*(Uint16*)(&data[1]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, FilterLeftThumb(axis));
axis = (int)*(Uint16*)(&data[3]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, FilterLeftThumb(axis));
axis = (int)*(Uint16*)(&data[5]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, FilterRightThumb(axis));
axis = (int)*(Uint16*)(&data[7]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, FilterRightThumb(axis));
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}

View File

@@ -110,96 +110,11 @@ HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float
static void HIDAPI_JoystickDetect(void);
static void HIDAPI_JoystickClose(SDL_Joystick *joystick);
static SDL_GameControllerType
SDL_GetJoystickGameControllerProtocol(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
static const int XB360_IFACE_SUBCLASS = 93;
static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
static const int XBONE_IFACE_SUBCLASS = 71;
static const int XBONE_IFACE_PROTOCOL = 208;
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
/* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XB360_IFACE_SUBCLASS &&
(interface_protocol == XB360_IFACE_PROTOCOL ||
interface_protocol == XB360W_IFACE_PROTOCOL)) {
static const int SUPPORTED_VENDORS[] = {
0x0079, /* GPD Win 2 */
0x044f, /* Thrustmaster */
0x045e, /* Microsoft */
0x046d, /* Logitech */
0x056e, /* Elecom */
0x06a3, /* Saitek */
0x0738, /* Mad Catz */
0x07ff, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1038, /* SteelSeries */
0x11c9, /* Nacon */
0x12ab, /* Unknown */
0x1430, /* RedOctane */
0x146b, /* BigBen */
0x1532, /* Razer */
0x15e4, /* Numark */
0x162e, /* Joytech */
0x1689, /* Razer Onza */
0x1949, /* Lab126, Inc. */
0x1bad, /* Harmonix */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2c22, /* Qanba */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
}
}
}
if (interface_number == 0 &&
interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XBONE_IFACE_SUBCLASS &&
interface_protocol == XBONE_IFACE_PROTOCOL) {
static const int SUPPORTED_VENDORS[] = {
0x045e, /* Microsoft */
0x0738, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1532, /* Razer */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2e24, /* Hyperkin */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
}
}
}
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_FALSE);
}
return type;
}
static SDL_bool
HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
{
int i;
SDL_GameControllerType type = SDL_GetJoystickGameControllerProtocol(name, vendor_id, product_id, -1, 0, 0, 0);
SDL_GameControllerType type = SDL_GetJoystickGameControllerType(name, vendor_id, product_id, -1, 0, 0, 0);
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
@@ -219,8 +134,14 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
const Uint16 USAGE_MULTIAXISCONTROLLER = 0x0008;
int i;
SDL_GameControllerType type;
SDL_JoystickGUID check_guid;
if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) {
/* Make sure we have a generic GUID here, otherwise if we pass a HIDAPI
guid, this call will create a game controller mapping for the device.
*/
check_guid = device->guid;
check_guid.data[14] = 0;
if (SDL_ShouldIgnoreJoystick(device->name, check_guid)) {
return NULL;
}
@@ -233,7 +154,7 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
}
}
type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
type = SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
if (driver->enabled && driver->IsSupportedDevice(device->name, type, device->vendor_id, device->product_id, device->version, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol)) {
@@ -285,8 +206,8 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device)
device->driver = HIDAPI_GetDeviceDriver(device);
if (device->driver) {
const char *name = device->driver->GetDeviceName(device->name, device->vendor_id, device->product_id);
if (name && name != device->name) {
const char *name = device->driver->GetDeviceName(device->vendor_id, device->product_id);
if (name) {
SDL_free(device->name);
device->name = SDL_strdup(name);
}
@@ -306,7 +227,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
}
/* Disconnect any joysticks */
while (device->num_joysticks && device->joysticks) {
while (device->num_joysticks) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
@@ -388,7 +309,8 @@ HIDAPI_JoystickInit(void)
#endif
if (SDL_hid_init() < 0) {
return SDL_SetError("Couldn't initialize hidapi");
SDL_SetError("Couldn't initialize hidapi");
return -1;
}
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
@@ -542,6 +464,38 @@ HIDAPI_AddDevice(struct SDL_hid_device_info *info)
char *serial_number = HIDAPI_ConvertString(info->serial_number);
device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string);
if (SDL_strncmp(device->name, "0x", 2) == 0) {
/* Couldn't find a controller name, try to give it one based on device type */
const char *name = NULL;
switch (SDL_GetJoystickGameControllerType(NULL, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol)) {
case SDL_CONTROLLER_TYPE_XBOX360:
name = "Xbox 360 Controller";
break;
case SDL_CONTROLLER_TYPE_XBOXONE:
name = "Xbox One Controller";
break;
case SDL_CONTROLLER_TYPE_PS3:
name = "PS3 Controller";
break;
case SDL_CONTROLLER_TYPE_PS4:
name = "PS4 Controller";
break;
case SDL_CONTROLLER_TYPE_PS5:
name = "PS5 Controller";
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
name = "Nintendo Switch Pro Controller";
break;
default:
break;
}
if (name) {
SDL_free(device->name);
device->name = SDL_strdup(name);
}
}
if (manufacturer_string) {
SDL_free(manufacturer_string);
@@ -674,13 +628,13 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi
/* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */
if (product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER &&
SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
return SDL_TRUE;
}
/* If we're looking for an XInput controller, match it against any other Xbox controller */
if (product_id == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
SDL_GameControllerType type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
SDL_GameControllerType type = SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
if (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) {
return SDL_TRUE;
}
@@ -709,7 +663,7 @@ HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type)
device = SDL_HIDAPI_devices;
while (device) {
if (device->driver &&
SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) {
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) {
result = SDL_TRUE;
break;
}
@@ -830,21 +784,6 @@ HIDAPI_JoystickGetDeviceName(int device_index)
return name;
}
static const char *
HIDAPI_JoystickGetDevicePath(int device_index)
{
SDL_HIDAPI_Device *device;
const char *path = NULL;
device = HIDAPI_GetDeviceByIndex(device_index, NULL);
if (device) {
/* FIXME: The device could be freed after this path is returned... */
path = device->path;
}
return path;
}
static int
HIDAPI_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -932,7 +871,8 @@ HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint1
result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble);
} else {
result = SDL_SetError("Rumble failed, device disconnected");
SDL_SetError("Rumble failed, device disconnected");
result = -1;
}
return result;
@@ -948,7 +888,8 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
result = device->driver->RumbleJoystickTriggers(device, joystick, left_rumble, right_rumble);
} else {
result = SDL_SetError("Rumble failed, device disconnected");
SDL_SetError("Rumble failed, device disconnected");
result = -1;
}
return result;
@@ -978,7 +919,8 @@ HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue
result = device->driver->SetJoystickLED(device, joystick, red, green, blue);
} else {
result = SDL_SetError("SetLED failed, device disconnected");
SDL_SetError("SetLED failed, device disconnected");
result = -1;
}
return result;
@@ -994,7 +936,8 @@ HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
result = device->driver->SendJoystickEffect(device, joystick, data, size);
} else {
result = SDL_SetError("SendEffect failed, device disconnected");
SDL_SetError("SendEffect failed, device disconnected");
result = -1;
}
return result;
@@ -1010,7 +953,8 @@ HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled);
} else {
result = SDL_SetError("SetSensorsEnabled failed, device disconnected");
SDL_SetError("SetSensorsEnabled failed, device disconnected");
result = -1;
}
return result;
@@ -1092,7 +1036,6 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickGetCount,
HIDAPI_JoystickDetect,
HIDAPI_JoystickGetDeviceName,
HIDAPI_JoystickGetDevicePath,
HIDAPI_JoystickGetDevicePlayerIndex,
HIDAPI_JoystickSetDevicePlayerIndex,
HIDAPI_JoystickGetDeviceGUID,

View File

@@ -90,7 +90,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
SDL_bool enabled;
SDL_bool enabled_default;
SDL_bool (*IsSupportedDevice)(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol);
const char *(*GetDeviceName)(const char *name, Uint16 vendor_id, Uint16 product_id);
const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device);
int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id);
void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);

View File

@@ -69,9 +69,6 @@ static NSString *GCInputXboxShareButton = @"Button Share";
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000))
@property(nonatomic, readonly) NSString *productCategory;
#endif
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 140500) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140500) || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 110300))
@property(class, nonatomic, readwrite) BOOL shouldMonitorBackgroundEvents;
#endif
@end
@interface GCExtendedGamepad (SDL)
#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 121000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1401000))
@@ -180,10 +177,6 @@ IsControllerXbox(GCController *controller)
static BOOL
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
{
if ((@available(macOS 11.3, *)) && !GCController.shouldMonitorBackgroundEvents) {
GCController.shouldMonitorBackgroundEvents = YES;
}
Uint16 *guid16 = (Uint16 *)device->guid.data;
Uint16 vendor = 0;
Uint16 product = 0;
@@ -334,15 +327,6 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
subtype = 1;
}
if (SDL_strcmp(name, "Backbone One") == 0) {
/* The Backbone app uses share button */
if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) {
device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1);
--nbuttons;
device->has_xbox_share_button = SDL_FALSE;
}
}
device->naxes = 6; /* 2 thumbsticks and 2 triggers */
device->nhats = 1; /* d-pad */
device->nbuttons = nbuttons;
@@ -647,12 +631,6 @@ IOS_JoystickGetDeviceName(int device_index)
return device ? device->name : "Unknown";
}
static const char *
IOS_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
IOS_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -741,7 +719,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
}
#ifdef ENABLE_MFI_SENSORS
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = joystick->hwdata->controller;
GCMotion *motion = controller.motion;
if (motion && motion.hasRotationRate) {
@@ -754,7 +732,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index)
#endif /* ENABLE_MFI_SENSORS */
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = joystick->hwdata->controller;
for (id key in controller.physicalInputProfile.buttons) {
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
@@ -966,7 +944,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
}
#ifdef ENABLE_MFI_SENSORS
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCMotion *motion = controller.motion;
if (motion && motion.sensorsActive) {
float data[3];
@@ -1059,7 +1037,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
}
#ifdef ENABLE_MFI_BATTERY
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
GCDeviceBattery *battery = controller.battery;
if (battery) {
SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN;
@@ -1100,8 +1078,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
#ifdef ENABLE_MFI_RUMBLE
@interface SDL_RumbleMotor : NSObject
@property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0));
@property(nonatomic,strong) id<CHHapticPatternPlayer> player API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0));
@property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
@property(nonatomic,strong) id<CHHapticPatternPlayer> player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0));
@property bool active;
@end
@@ -1111,7 +1089,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
-(void)cleanup
{
@autoreleasepool {
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
if (self.player != nil) {
[self.player cancelAndReturnError:nil];
self.player = nil;
@@ -1127,7 +1105,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
-(int)setIntensity:(float)intensity
{
@autoreleasepool {
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
NSError *error = nil;
if (self.engine == nil) {
@@ -1173,7 +1151,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
}
}
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0))
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
{
@autoreleasepool {
self = [super init];
@@ -1191,7 +1169,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
return nil;
}
__weak __typeof(self) weakSelf = self;
__weak typeof(self) weakSelf = self;
self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) {
SDL_RumbleMotor *_this = weakSelf;
if (_this == nil) {
@@ -1273,7 +1251,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller)
{
@autoreleasepool {
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
SDL_RumbleMotor *low_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftHandle];
SDL_RumbleMotor *high_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityRightHandle];
SDL_RumbleMotor *left_trigger_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftTrigger];
@@ -1301,7 +1279,7 @@ IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
return SDL_SetError("Controller is no longer connected");
}
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
if (!device->rumble && device->controller && device->controller.haptics) {
SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
if (rumble) {
@@ -1331,7 +1309,7 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
return SDL_SetError("Controller is no longer connected");
}
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
if (!device->rumble && device->controller && device->controller.haptics) {
SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller);
if (rumble) {
@@ -1364,7 +1342,7 @@ IOS_JoystickGetCapabilities(SDL_Joystick *joystick)
return 0;
}
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = device->controller;
#ifdef ENABLE_MFI_LIGHT
if (controller.light) {
@@ -1401,7 +1379,7 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
return SDL_SetError("Controller is no longer connected");
}
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = device->controller;
GCDeviceLight *light = controller.light;
if (light) {
@@ -1434,7 +1412,7 @@ IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
return SDL_SetError("Controller is no longer connected");
}
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
GCController *controller = device->controller;
GCMotion *motion = controller.motion;
if (motion) {
@@ -1497,7 +1475,7 @@ IOS_JoystickClose(SDL_Joystick *joystick)
controller.playerIndex = -1;
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
for (id key in controller.physicalInputProfile.buttons) {
GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key];
if ([button isBoundToSystemGesture]) {
@@ -1595,7 +1573,7 @@ SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device)
static void
GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name)
{
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
if (element) {
[element.sfSymbolsName getCString: name maxLength: 255 encoding: NSASCIIStringEncoding];
}
@@ -1629,7 +1607,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontrol
elementName[0] = '\0';
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) {
GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller;
if ([controller respondsToSelector:@selector(physicalInputProfile)]) {
NSDictionary<NSString *,GCControllerElement *> *elements = controller.physicalInputProfile.elements;
@@ -1742,7 +1720,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontrolle
elementName[0] = '\0';
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) {
GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller;
if ([controller respondsToSelector:@selector(physicalInputProfile)]) {
NSDictionary<NSString *,GCControllerElement *> *elements = controller.physicalInputProfile.elements;
@@ -1783,7 +1761,6 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
IOS_JoystickGetCount,
IOS_JoystickDetect,
IOS_JoystickGetDeviceName,
IOS_JoystickGetDevicePath,
IOS_JoystickGetDevicePlayerIndex,
IOS_JoystickSetDevicePlayerIndex,
IOS_JoystickGetDeviceGUID,

View File

@@ -82,10 +82,6 @@
#define DEBUG_INPUT_EVENTS 1
#endif
#if 0
#define DEBUG_GAMEPAD_MAPPING 1
#endif
typedef enum
{
ENUMERATION_UNSET,
@@ -113,7 +109,6 @@ typedef struct SDL_joylist_item
/* Steam Controller support */
SDL_bool m_bSteamController;
SDL_bool checked_mapping;
SDL_GamepadMapping *mapping;
} SDL_joylist_item;
@@ -497,6 +492,21 @@ static void SteamControllerDisconnectedCallback(int device_instance)
}
}
#ifdef HAVE_INOTIFY
#ifdef HAVE_INOTIFY_INIT1
static int SDL_inotify_init1(void) {
return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
}
#else
static int SDL_inotify_init1(void) {
int fd = inotify_init();
if (fd < 0) return -1;
fcntl(fd, F_SETFL, O_NONBLOCK);
fcntl(fd, F_SETFD, FD_CLOEXEC);
return fd;
}
#endif
static int
StrHasPrefix(const char *string, const char *prefix)
{
@@ -551,21 +561,6 @@ IsJoystickDeviceNode(const char *node)
}
}
#ifdef HAVE_INOTIFY
#ifdef HAVE_INOTIFY_INIT1
static int SDL_inotify_init1(void) {
return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
}
#else
static int SDL_inotify_init1(void) {
int fd = inotify_init();
if (fd < 0) return -1;
fcntl(fd, F_SETFL, O_NONBLOCK);
fcntl(fd, F_SETFD, FD_CLOEXEC);
return fd;
}
#endif
static void
LINUX_InotifyJoystickDetect(void)
{
@@ -610,26 +605,6 @@ LINUX_InotifyJoystickDetect(void)
}
#endif /* HAVE_INOTIFY */
static int get_event_joystick_index(int event)
{
int joystick_index = -1;
int i, count;
struct dirent **entries = NULL;
char path[PATH_MAX];
SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
count = scandir(path, &entries, NULL, alphasort);
for (i = 0; i < count; ++i) {
if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
joystick_index = SDL_atoi(entries[i]->d_name+2);
}
free(entries[i]); /* This should NOT be SDL_free() */
}
free(entries); /* This should NOT be SDL_free() */
return joystick_index;
}
/* Detect devices by reading /dev/input. In the inotify code path we
* have to do this the first time, to detect devices that already existed
* before we started; in the non-inotify code path we do this repeatedly
@@ -640,39 +615,12 @@ filter_entries(const struct dirent *entry)
return IsJoystickDeviceNode(entry->d_name);
}
static int
sort_entries(const void *_a, const void *_b)
sort_entries(const struct dirent **a, const struct dirent **b)
{
const struct dirent **a = (const struct dirent **)_a;
const struct dirent **b = (const struct dirent **)_b;
int numA, numB;
int offset;
if (SDL_classic_joysticks) {
offset = 2; /* strlen("js") */
numA = SDL_atoi((*a)->d_name+offset);
numB = SDL_atoi((*b)->d_name+offset);
} else {
offset = 5; /* strlen("event") */
numA = SDL_atoi((*a)->d_name+offset);
numB = SDL_atoi((*b)->d_name+offset);
/* See if we can get the joystick ordering */
{
int jsA = get_event_joystick_index(numA);
int jsB = get_event_joystick_index(numB);
if (jsA >= 0 && jsB >= 0) {
numA = jsA;
numB = jsB;
} else if (jsA >= 0) {
return -1;
} else if (jsB >= 0) {
return 1;
}
}
}
int numA = SDL_atoi((*a)->d_name+5);
int numB = SDL_atoi((*b)->d_name+5);
return (numA - numB);
}
static void
LINUX_FallbackJoystickDetect(void)
{
@@ -685,13 +633,10 @@ LINUX_FallbackJoystickDetect(void)
/* Opening input devices can generate synchronous device I/O, so avoid it if we can */
if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
int i, count;
struct dirent **entries = NULL;
struct dirent **entries;
char path[PATH_MAX];
count = scandir("/dev/input", &entries, filter_entries, NULL);
if (count > 1) {
qsort(entries, count, sizeof(*entries), sort_entries);
}
count = scandir("/dev/input", &entries, filter_entries, sort_entries);
for (i = 0; i < count; ++i) {
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
MaybeAddDevice(path);
@@ -738,7 +683,29 @@ LINUX_JoystickInit(void)
SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
enumeration_method = ENUMERATION_UNSET;
#if SDL_USE_LIBUDEV
if (enumeration_method == ENUMERATION_UNSET) {
if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
enumeration_method = ENUMERATION_FALLBACK;
} else if (access("/.flatpak-info", F_OK) == 0
|| access("/run/host/container-manager", F_OK) == 0) {
/* Explicitly check `/.flatpak-info` because, for old versions of
* Flatpak, this was the only available way to tell if we were in
* a Flatpak container. */
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling udev integration");
enumeration_method = ENUMERATION_FALLBACK;
} else {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Using udev for joystick device discovery");
enumeration_method = ENUMERATION_LIBUDEV;
}
}
#endif
/* First see if the user specified one or more joysticks to use */
if (devices != NULL) {
@@ -767,28 +734,6 @@ LINUX_JoystickInit(void)
LINUX_JoystickDetect();
#if SDL_USE_LIBUDEV
if (enumeration_method == ENUMERATION_UNSET) {
if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
enumeration_method = ENUMERATION_FALLBACK;
} else if (access("/.flatpak-info", F_OK) == 0
|| access("/run/host/container-manager", F_OK) == 0) {
/* Explicitly check `/.flatpak-info` because, for old versions of
* Flatpak, this was the only available way to tell if we were in
* a Flatpak container. */
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling udev integration");
enumeration_method = ENUMERATION_FALLBACK;
} else {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Using udev for joystick device discovery");
enumeration_method = ENUMERATION_LIBUDEV;
}
}
if (enumeration_method == ENUMERATION_LIBUDEV) {
if (SDL_UDEV_Init() < 0) {
return SDL_SetError("Could not initialize UDEV");
@@ -858,18 +803,13 @@ JoystickByDevIndex(int device_index)
return item;
}
/* Function to get the device-dependent name of a joystick */
static const char *
LINUX_JoystickGetDeviceName(int device_index)
{
return JoystickByDevIndex(device_index)->name;
}
static const char *
LINUX_JoystickGetDevicePath(int device_index)
{
return JoystickByDevIndex(device_index)->path;
}
static int
LINUX_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -930,37 +870,6 @@ allocate_balldata(SDL_Joystick *joystick)
return (0);
}
static SDL_bool
GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y)
{
/* A "hat" is assumed to be a digital input with at most 9 possible states
* (3 per axis: negative/zero/positive), as opposed to a true "axis" which
* can report a continuous range of possible values. Unfortunately the Linux
* joystick interface makes no distinction between digital hat axes and any
* other continuous analog axis, so we have to guess. */
/* If both axes are missing, they're not anything. */
if (!absinfo_x && !absinfo_y)
return SDL_FALSE;
/* If the hint says so, treat all hats as digital. */
if (SDL_GetHintBoolean(SDL_HINT_LINUX_DIGITAL_HATS, SDL_FALSE))
return SDL_TRUE;
/* If both axes have ranges constrained between -1 and 1, they're definitely digital. */
if ((!absinfo_x || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) &&
(!absinfo_y || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1)))
return SDL_TRUE;
/* If both axes lack fuzz, flat, and resolution values, they're probably digital. */
if ((!absinfo_x || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) &&
(!absinfo_y || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution)))
return SDL_TRUE;
/* Otherwise, treat them as analog. */
return SDL_FALSE;
}
static void
ConfigJoystick(SDL_Joystick *joystick, int fd)
{
@@ -971,7 +880,6 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
unsigned long ffbit[NBITS(FF_MAX)] = { 0 };
Uint8 key_pam_size, abs_pam_size;
SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE);
SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE);
/* See if this device uses the new unified event API */
if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&
@@ -999,45 +907,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
++joystick->nbuttons;
}
}
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
int hat_x = -1;
int hat_y = -1;
struct input_absinfo absinfo_x;
struct input_absinfo absinfo_y;
if (test_bit(i, absbit))
hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x);
if (test_bit(i + 1, absbit))
hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y);
if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void*)0 : &absinfo_x),
(hat_y < 0 ? (void*)0 : &absinfo_y))) {
const int hat_index = (i - ABS_HAT0X) / 2;
struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index];
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has digital hat: #%d\n", hat_index);
if (hat_x >= 0) {
SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum,
absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution);
}
if (hat_y >= 0) {
SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum,
absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution);
}
#endif /* DEBUG_INPUT_EVENTS */
joystick->hwdata->hats_indices[hat_index] = joystick->nhats;
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
correct->use_deadzones = use_hat_deadzones;
correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum;
correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum;
correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum;
correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum;
++joystick->nhats;
}
}
for (i = 0; i < ABS_MAX; ++i) {
/* Skip digital hats */
if (joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
/* Skip hats */
if (i == ABS_HAT0X) {
i = ABS_HAT3Y;
continue;
}
if (test_bit(i, absbit)) {
@@ -1049,9 +922,9 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
}
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has absolute axis: 0x%.2x\n", i);
SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n",
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
absinfo.value, absinfo.minimum, absinfo.maximum,
absinfo.fuzz, absinfo.flat, absinfo.resolution);
absinfo.fuzz, absinfo.flat);
#endif /* DEBUG_INPUT_EVENTS */
joystick->hwdata->abs_map[i] = joystick->naxes;
joystick->hwdata->has_abs[i] = SDL_TRUE;
@@ -1079,6 +952,24 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
++joystick->naxes;
}
}
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) {
if (test_bit(i, absbit) || test_bit(i + 1, absbit)) {
struct input_absinfo absinfo;
int hat_index = (i - ABS_HAT0X) / 2;
if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) {
continue;
}
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has hat %d\n", hat_index);
SDL_Log("Values = { %d, %d, %d, %d, %d }\n",
absinfo.value, absinfo.minimum, absinfo.maximum,
absinfo.fuzz, absinfo.flat);
#endif /* DEBUG_INPUT_EVENTS */
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
}
}
if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) {
++joystick->nballs;
}
@@ -1124,19 +1015,14 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
for (i = 0; i < abs_pam_size; ++i) {
Uint8 code = joystick->hwdata->abs_pam[i];
// TODO: is there any way to detect analog hats in advance via this API?
if (code >= ABS_HAT0X && code <= ABS_HAT3Y) {
int hat_index = (code - ABS_HAT0X) / 2;
if (!joystick->hwdata->has_hat[hat_index]) {
#ifdef DEBUG_INPUT_EVENTS
SDL_Log("Joystick has digital hat: #%d\n", hat_index);
SDL_Log("Joystick has hat %d\n", hat_index);
#endif
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
joystick->hwdata->hat_correct[hat_index].minimum[0] = -1;
joystick->hwdata->hat_correct[hat_index].maximum[0] = 1;
joystick->hwdata->hat_correct[hat_index].minimum[1] = -1;
joystick->hwdata->hat_correct[hat_index].maximum[1] = 1;
}
} else {
#ifdef DEBUG_INPUT_EVENTS
@@ -1335,48 +1221,26 @@ LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
}
static void
HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value)
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
{
const int hatnum = stick->hwdata->hats_indices[hatidx];
struct hwdata_hat *the_hat;
struct hat_axis_correct *correct;
const Uint8 position_map[3][3] = {
{SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP},
{SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT},
{SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN}
};
the_hat = &stick->hwdata->hats[hatnum];
correct = &stick->hwdata->hat_correct[hatidx];
/* Hopefully we detected any analog axes and left them as is rather than trying
* to use them as digital hats, but just in case, the deadzones here will
* prevent the slightest of twitches on an analog axis from registering as a hat
* movement. If the axes really are digital, this won't hurt since they should
* only ever be sending min, 0, or max anyway. */
the_hat = &stick->hwdata->hats[hat];
if (value < 0) {
if (value <= correct->minimum[axis]) {
correct->minimum[axis] = value;
value = 0;
} else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) {
value = 0;
} else {
value = 1;
}
} else if (value > 0) {
if (value >= correct->maximum[axis]) {
correct->maximum[axis] = value;
value = 2;
} else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) {
value = 2;
} else {
value = 1;
}
} else { // value == 0
value = 0;
} else if (value == 0) {
value = 1;
} else if (value > 0) {
value = 2;
}
if (value != the_hat->axis[axis]) {
the_hat->axis[axis] = value;
SDL_PrivateJoystickHat(stick, hatnum,
SDL_PrivateJoystickHat(stick, hat,
position_map[the_hat->axis[1]][the_hat->axis[0]]);
}
}
@@ -1431,7 +1295,10 @@ PollAllValues(SDL_Joystick *joystick)
/* Poll all axis */
for (i = ABS_X; i < ABS_MAX; i++) {
/* We don't need to test for digital hats here, they won't have has_abs[] set */
if (i == ABS_HAT0X) { /* we handle hats in the next loop, skip them for now. */
i = ABS_HAT3Y;
continue;
}
if (joystick->hwdata->has_abs[i]) {
if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
absinfo.value = AxisCorrect(joystick, i, absinfo.value);
@@ -1447,16 +1314,15 @@ PollAllValues(SDL_Joystick *joystick)
}
}
/* Poll all digital hats */
/* Poll all hats */
for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) {
const int baseaxis = i - ABS_HAT0X;
const int hatidx = baseaxis / 2;
SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat));
/* We don't need to test for analog axes here, they won't have has_hat[] set */
if (joystick->hwdata->has_hat[hatidx]) {
if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) {
const int hataxis = baseaxis % 2;
HandleHat(joystick, hatidx, hataxis, absinfo.value);
HandleHat(joystick, joystick->hwdata->hats_indices[hatidx], hataxis, absinfo.value);
}
}
}
@@ -1484,7 +1350,7 @@ static void
HandleInputEvents(SDL_Joystick *joystick)
{
struct input_event events[32];
int i, len, code, hat_index;
int i, len, code;
if (joystick->hwdata->fresh) {
PollAllValues(joystick);
@@ -1519,11 +1385,9 @@ HandleInputEvents(SDL_Joystick *joystick)
case ABS_HAT2Y:
case ABS_HAT3X:
case ABS_HAT3Y:
hat_index = (code - ABS_HAT0X) / 2;
if (joystick->hwdata->has_hat[hat_index]) {
HandleHat(joystick, hat_index, code % 2, events[i].value);
break;
}
code -= ABS_HAT0X;
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
break;
default:
events[i].value = AxisCorrect(joystick, code, events[i].value);
SDL_PrivateJoystickAxis(joystick,
@@ -1576,7 +1440,7 @@ static void
HandleClassicEvents(SDL_Joystick *joystick)
{
struct js_event events[32];
int i, len, code, hat_index;
int i, len, code;
joystick->hwdata->fresh = SDL_FALSE;
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
@@ -1600,11 +1464,9 @@ HandleClassicEvents(SDL_Joystick *joystick)
case ABS_HAT2Y:
case ABS_HAT3X:
case ABS_HAT3Y:
hat_index = (code - ABS_HAT0X) / 2;
if (joystick->hwdata->has_hat[hat_index]) {
HandleHat(joystick, hat_index, code % 2, events[i].value);
break;
}
code -= ABS_HAT0X;
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
break;
default:
SDL_PrivateJoystickAxis(joystick,
joystick->hwdata->abs_map[code],
@@ -1710,18 +1572,10 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
SDL_Joystick *joystick;
SDL_joylist_item *item = JoystickByDevIndex(device_index);
unsigned int mapped;
if (item->checked_mapping) {
if (item->mapping) {
SDL_memcpy(out, item->mapping, sizeof(*out));
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Prior mapping for device %d", device_index);
#endif
return SDL_TRUE;
} else {
return SDL_FALSE;
}
if (item->mapping) {
SDL_memcpy(out, item->mapping, sizeof(*out));
return SDL_TRUE;
}
/* We temporarily open the device to check how it's configured. Make
@@ -1741,8 +1595,6 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
return SDL_FALSE;
}
item->checked_mapping = SDL_TRUE;
if (PrepareJoystickHwdata(joystick, item) == -1) {
SDL_free(joystick->hwdata);
SDL_free(joystick);
@@ -1765,17 +1617,11 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
if (joystick->hwdata->has_key[BTN_A]) {
out->a.kind = EMappingKind_Button;
out->a.target = joystick->hwdata->key_map[BTN_A];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped A to button %d (BTN_A)", out->a.target);
#endif
}
if (joystick->hwdata->has_key[BTN_B]) {
out->b.kind = EMappingKind_Button;
out->b.target = joystick->hwdata->key_map[BTN_B];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped B to button %d (BTN_B)", out->b.target);
#endif
}
/* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */
@@ -1783,74 +1629,47 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
if (joystick->hwdata->has_key[BTN_WEST]) {
out->x.kind = EMappingKind_Button;
out->x.target = joystick->hwdata->key_map[BTN_WEST];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target);
#endif
}
if (joystick->hwdata->has_key[BTN_NORTH]) {
out->y.kind = EMappingKind_Button;
out->y.target = joystick->hwdata->key_map[BTN_NORTH];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target);
#endif
}
} else {
if (joystick->hwdata->has_key[BTN_X]) {
out->x.kind = EMappingKind_Button;
out->x.target = joystick->hwdata->key_map[BTN_X];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped X to button %d (BTN_X)", out->x.target);
#endif
}
if (joystick->hwdata->has_key[BTN_Y]) {
out->y.kind = EMappingKind_Button;
out->y.target = joystick->hwdata->key_map[BTN_Y];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target);
#endif
}
}
if (joystick->hwdata->has_key[BTN_SELECT]) {
out->back.kind = EMappingKind_Button;
out->back.target = joystick->hwdata->key_map[BTN_SELECT];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target);
#endif
}
if (joystick->hwdata->has_key[BTN_START]) {
out->start.kind = EMappingKind_Button;
out->start.target = joystick->hwdata->key_map[BTN_START];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped START to button %d (BTN_START)", out->start.target);
#endif
}
if (joystick->hwdata->has_key[BTN_THUMBL]) {
out->leftstick.kind = EMappingKind_Button;
out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target);
#endif
}
if (joystick->hwdata->has_key[BTN_THUMBR]) {
out->rightstick.kind = EMappingKind_Button;
out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target);
#endif
}
if (joystick->hwdata->has_key[BTN_MODE]) {
out->guide.kind = EMappingKind_Button;
out->guide.target = joystick->hwdata->key_map[BTN_MODE];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target);
#endif
}
/*
@@ -1858,191 +1677,84 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
can be digital, or analog, or both at the same time.
*/
/* Prefer digital shoulder buttons, but settle for digital or analog hat. */
mapped = 0;
/* Prefer digital shoulder buttons, but settle for analog if missing. */
if (joystick->hwdata->has_key[BTN_TL]) {
out->leftshoulder.kind = EMappingKind_Button;
out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target);
#endif
}
if (joystick->hwdata->has_key[BTN_TR]) {
out->rightshoulder.kind = EMappingKind_Button;
out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target);
#endif
}
if (mapped != 0x3 && joystick->hwdata->has_hat[1]) {
if (joystick->hwdata->has_hat[1] && /* Check if ABS_HAT1{X, Y} is available. */
(!joystick->hwdata->has_key[BTN_TL] || !joystick->hwdata->has_key[BTN_TR])) {
int hat = joystick->hwdata->hats_indices[1] << 4;
out->leftshoulder.kind = EMappingKind_Hat;
out->rightshoulder.kind = EMappingKind_Hat;
out->leftshoulder.target = hat | 0x4;
out->rightshoulder.target = hat | 0x2;
mapped |= 0x3;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)");
#endif
}
if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) {
out->leftshoulder.kind = EMappingKind_Axis;
out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target);
#endif
}
if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) {
out->rightshoulder.kind = EMappingKind_Axis;
out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target);
#endif
}
/* Prefer analog triggers, but settle for digital hat or buttons. */
mapped = 0;
if (joystick->hwdata->has_abs[ABS_HAT2Y]) {
out->lefttrigger.kind = EMappingKind_Axis;
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target);
#endif
} else if (joystick->hwdata->has_abs[ABS_Z]) {
out->lefttrigger.kind = EMappingKind_Axis;
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target);
#endif
}
if (joystick->hwdata->has_abs[ABS_HAT2X]) {
out->righttrigger.kind = EMappingKind_Axis;
out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target);
#endif
} else if (joystick->hwdata->has_abs[ABS_RZ]) {
out->righttrigger.kind = EMappingKind_Axis;
out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target);
#endif
}
if (mapped != 0x3 && joystick->hwdata->has_hat[2]) {
/* Prefer analog triggers, but settle for digital if missing. */
if (joystick->hwdata->has_hat[2]) { /* Check if ABS_HAT2{X,Y} is available. */
int hat = joystick->hwdata->hats_indices[2] << 4;
out->lefttrigger.kind = EMappingKind_Hat;
out->righttrigger.kind = EMappingKind_Hat;
out->lefttrigger.target = hat | 0x4;
out->righttrigger.target = hat | 0x2;
mapped |= 0x3;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)");
#endif
} else {
if (joystick->hwdata->has_abs[ABS_Z]) {
out->lefttrigger.kind = EMappingKind_Axis;
out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z];
} else if (joystick->hwdata->has_key[BTN_TL2]) {
out->lefttrigger.kind = EMappingKind_Button;
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
}
if (joystick->hwdata->has_abs[ABS_RZ]) {
out->righttrigger.kind = EMappingKind_Axis;
out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ];
} else if (joystick->hwdata->has_key[BTN_TR2]) {
out->righttrigger.kind = EMappingKind_Button;
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
}
}
if (!(mapped & 0x1) && joystick->hwdata->has_key[BTN_TL2]) {
out->lefttrigger.kind = EMappingKind_Button;
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target);
#endif
}
if (!(mapped & 0x2) && joystick->hwdata->has_key[BTN_TR2]) {
out->righttrigger.kind = EMappingKind_Button;
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target);
#endif
}
/* Prefer digital D-Pad buttons, but settle for digital or analog hat. */
mapped = 0;
/* Prefer digital D-Pad, but settle for analog if missing. */
if (joystick->hwdata->has_key[BTN_DPAD_UP]) {
out->dpup.kind = EMappingKind_Button;
out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP];
mapped |= 0x1;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target);
#endif
}
if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) {
out->dpdown.kind = EMappingKind_Button;
out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN];
mapped |= 0x2;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target);
#endif
}
if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) {
out->dpleft.kind = EMappingKind_Button;
out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT];
mapped |= 0x4;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target);
#endif
}
if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) {
out->dpright.kind = EMappingKind_Button;
out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT];
mapped |= 0x8;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target);
#endif
}
if (mapped != 0xF) {
if (joystick->hwdata->has_hat[0]) {
int hat = joystick->hwdata->hats_indices[0] << 4;
out->dpleft.kind = EMappingKind_Hat;
out->dpright.kind = EMappingKind_Hat;
out->dpup.kind = EMappingKind_Hat;
out->dpdown.kind = EMappingKind_Hat;
out->dpleft.target = hat | 0x8;
out->dpright.target = hat | 0x2;
out->dpup.target = hat | 0x1;
out->dpdown.target = hat | 0x4;
mapped |= 0xF;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)");
#endif
} else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) {
out->dpleft.kind = EMappingKind_Axis;
out->dpright.kind = EMappingKind_Axis;
out->dpup.kind = EMappingKind_Axis;
out->dpdown.kind = EMappingKind_Axis;
out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X];
out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X];
out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y];
out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y];
mapped |= 0xF;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target);
SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target);
#endif
}
if (joystick->hwdata->has_hat[0] && /* Check if ABS_HAT0{X,Y} is available. */
(!joystick->hwdata->has_key[BTN_DPAD_LEFT] || !joystick->hwdata->has_key[BTN_DPAD_RIGHT] ||
!joystick->hwdata->has_key[BTN_DPAD_UP] || !joystick->hwdata->has_key[BTN_DPAD_DOWN])) {
int hat = joystick->hwdata->hats_indices[0] << 4;
out->dpleft.kind = EMappingKind_Hat;
out->dpright.kind = EMappingKind_Hat;
out->dpup.kind = EMappingKind_Hat;
out->dpdown.kind = EMappingKind_Hat;
out->dpleft.target = hat | 0x8;
out->dpright.target = hat | 0x2;
out->dpup.target = hat | 0x1;
out->dpdown.target = hat | 0x4;
}
if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) {
@@ -2050,10 +1762,6 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
out->lefty.kind = EMappingKind_Axis;
out->leftx.target = joystick->hwdata->abs_map[ABS_X];
out->lefty.target = joystick->hwdata->abs_map[ABS_Y];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target);
SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target);
#endif
}
if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) {
@@ -2061,10 +1769,6 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
out->righty.kind = EMappingKind_Axis;
out->rightx.target = joystick->hwdata->abs_map[ABS_RX];
out->righty.target = joystick->hwdata->abs_map[ABS_RY];
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target);
SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target);
#endif
}
LINUX_JoystickClose(joystick);
@@ -2075,9 +1779,6 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
if (item->mapping) {
SDL_memcpy(item->mapping, out, sizeof(*out));
}
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Generated mapping for device %d", device_index);
#endif
return SDL_TRUE;
}
@@ -2088,7 +1789,6 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickGetCount,
LINUX_JoystickDetect,
LINUX_JoystickGetDeviceName,
LINUX_JoystickGetDevicePath,
LINUX_JoystickGetDevicePlayerIndex,
LINUX_JoystickSetDevicePlayerIndex,
LINUX_JoystickGetDeviceGUID,

View File

@@ -83,12 +83,6 @@ struct joystick_hwdata
/* 4 = (ABS_HAT3X-ABS_HAT0X)/2 (see input-event-codes.h in kernel) */
int hats_indices[4];
SDL_bool has_hat[4];
struct hat_axis_correct
{
SDL_bool use_deadzones;
int minimum[2];
int maximum[2];
} hat_correct[4];
/* Set when gamepad is pending removal due to ENODEV read error */
SDL_bool gone;

View File

@@ -377,17 +377,15 @@ static void OS2_JoystickDetect(void)
{
}
/***********************************************************/
/* Function to get the device-dependent name of a joystick */
/***********************************************************/
static const char *OS2_JoystickGetDeviceName(int device_index)
{
/* No need to verify if device exists, already done in upper layer */
return SYS_JoyData[device_index].szDeviceName;
}
static const char *OS2_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int OS2_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
@@ -781,7 +779,6 @@ SDL_JoystickDriver SDL_OS2_JoystickDriver =
OS2_NumJoysticks,
OS2_JoystickDetect,
OS2_JoystickGetDeviceName,
OS2_JoystickGetDevicePath,
OS2_JoystickGetDevicePlayerIndex,
OS2_JoystickSetDevicePlayerIndex,
OS2_JoystickGetDeviceGUID,

View File

@@ -142,6 +142,7 @@ static void PSP_JoystickDetect(void)
}
#if 0
/* Function to get the device-dependent name of a joystick */
static const char *PSP_JoystickName(int idx)
{
if (idx == 0) return "PSP controller";
@@ -150,16 +151,12 @@ static const char *PSP_JoystickName(int idx)
}
#endif
/* Function to get the device-dependent name of a joystick */
static const char *PSP_JoystickGetDeviceName(int device_index)
{
return "PSP builtin joypad";
}
static const char *PSP_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int PSP_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
@@ -307,7 +304,6 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver =
PSP_NumJoysticks,
PSP_JoystickDetect,
PSP_JoystickGetDeviceName,
PSP_JoystickGetDevicePath,
PSP_JoystickGetDevicePlayerIndex,
PSP_JoystickSetDevicePlayerIndex,
PSP_JoystickGetDeviceGUID,

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
#
# Script to sort the game controller database entries in SDL_gamecontroller.c

View File

@@ -47,9 +47,6 @@
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT 0x2006
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT 0x2007
#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP 0x200e
#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019
#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e
#define USB_PRODUCT_NINTENDO_SNES_CONTROLLER 0x2017
#define USB_PRODUCT_RAZER_PANTHERA 0x0401
#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008
#define USB_PRODUCT_RAZER_ATROX 0x0a00
@@ -57,7 +54,6 @@
#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0
#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc
#define USB_PRODUCT_SONY_DS5 0x0ce6
#define USB_PRODUCT_VICTRIX_FS_PRO_V2 0x0207
#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 /* XUSB driver software PID */
#define USB_PRODUCT_XBOX360_WIRED_CONTROLLER 0x028e
#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719

View File

@@ -24,11 +24,11 @@
/* This is the virtual implementation of the SDL joystick API */
#include "SDL_endian.h"
#include "SDL_virtualjoystick_c.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
static joystick_hwdata * g_VJoys = NULL;
@@ -56,6 +56,18 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
if (!hwdata) {
return;
}
if (hwdata->axes) {
SDL_free((void *)hwdata->axes);
hwdata->axes = NULL;
}
if (hwdata->buttons) {
SDL_free((void *)hwdata->buttons);
hwdata->buttons = NULL;
}
if (hwdata->hats) {
SDL_free(hwdata->hats);
hwdata->hats = NULL;
}
/* Remove hwdata from SDL-global list */
while (cur) {
@@ -71,170 +83,51 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata)
cur = cur->next;
}
if (hwdata->joystick) {
hwdata->joystick->hwdata = NULL;
hwdata->joystick = NULL;
}
if (hwdata->name) {
SDL_free(hwdata->name);
hwdata->name = NULL;
}
if (hwdata->axes) {
SDL_free((void *)hwdata->axes);
hwdata->axes = NULL;
}
if (hwdata->buttons) {
SDL_free((void *)hwdata->buttons);
hwdata->buttons = NULL;
}
if (hwdata->hats) {
SDL_free(hwdata->hats);
hwdata->hats = NULL;
}
SDL_free(hwdata);
}
int
SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
int naxes,
int nbuttons,
int nhats)
{
joystick_hwdata *hwdata = NULL;
int device_index = -1;
const char *name = NULL;
Uint16 *guid16;
int axis_triggerleft = -1;
int axis_triggerright = -1;
if (!desc) {
return SDL_InvalidParamError("desc");
}
if (desc->version != SDL_VIRTUAL_JOYSTICK_DESC_VERSION) {
/* Is this an old version that we can support? */
return SDL_SetError("Unsupported virtual joystick description version %d", desc->version);
}
hwdata = SDL_calloc(1, sizeof(joystick_hwdata));
if (!hwdata) {
VIRTUAL_FreeHWData(hwdata);
return SDL_OutOfMemory();
}
SDL_memcpy(&hwdata->desc, desc, sizeof(*desc));
if (hwdata->desc.name) {
name = hwdata->desc.name;
} else {
switch (hwdata->desc.type) {
case SDL_JOYSTICK_TYPE_GAMECONTROLLER:
name = "Virtual Controller";
break;
case SDL_JOYSTICK_TYPE_WHEEL:
name = "Virtual Wheel";
break;
case SDL_JOYSTICK_TYPE_ARCADE_STICK:
name = "Virtual Arcade Stick";
break;
case SDL_JOYSTICK_TYPE_FLIGHT_STICK:
name = "Virtual Flight Stick";
break;
case SDL_JOYSTICK_TYPE_DANCE_PAD:
name = "Virtual Dance Pad";
break;
case SDL_JOYSTICK_TYPE_GUITAR:
name = "Virtual Guitar";
break;
case SDL_JOYSTICK_TYPE_DRUM_KIT:
name = "Virtual Drum Kit";
break;
case SDL_JOYSTICK_TYPE_ARCADE_PAD:
name = "Virtual Arcade Pad";
break;
case SDL_JOYSTICK_TYPE_THROTTLE:
name = "Virtual Throttle";
break;
default:
name = "Virtual Joystick";
break;
}
}
hwdata->name = SDL_strdup(name);
if (hwdata->desc.type == SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
int i, axis;
if (hwdata->desc.button_mask == 0) {
for (i = 0; i < hwdata->desc.nbuttons && i < sizeof(hwdata->desc.button_mask)*8; ++i) {
hwdata->desc.button_mask |= (1 << i);
}
}
if (hwdata->desc.axis_mask == 0) {
if (hwdata->desc.naxes >= 2) {
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY));
}
if (hwdata->desc.naxes >= 4) {
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY));
}
if (hwdata->desc.naxes >= 6) {
hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
}
}
/* Find the trigger axes */
axis = 0;
for (i = 0; axis < hwdata->desc.naxes && i < SDL_CONTROLLER_AXIS_MAX; ++i) {
if (hwdata->desc.axis_mask & (1 << i)) {
if (i == SDL_CONTROLLER_AXIS_TRIGGERLEFT) {
axis_triggerleft = axis;
}
if (i == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {
axis_triggerright = axis;
}
++axis;
}
}
}
/* We only need 16 bits for each of these; space them out to fill 128. */
/* Byteswap so devices get same GUID on little/big endian platforms. */
guid16 = (Uint16 *)hwdata->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(hwdata->desc.vendor_id);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(hwdata->desc.product_id);
*guid16++ = 0;
*guid16++ = 0;
*guid16++ = 0; /* This will be overwritten below with the virtual controller signature */
hwdata->naxes = naxes;
hwdata->nbuttons = nbuttons;
hwdata->nhats = nhats;
hwdata->name = "Virtual Joystick";
/* Note that this is a Virtual device and what subtype it is */
hwdata->guid.data[14] = 'v';
hwdata->guid.data[15] = (Uint8)hwdata->desc.type;
hwdata->guid.data[15] = (Uint8)type;
/* Allocate fields for different control-types */
if (hwdata->desc.naxes > 0) {
hwdata->axes = SDL_calloc(hwdata->desc.naxes, sizeof(Sint16));
if (naxes > 0) {
hwdata->axes = SDL_calloc(naxes, sizeof(Sint16));
if (!hwdata->axes) {
VIRTUAL_FreeHWData(hwdata);
return SDL_OutOfMemory();
}
/* Trigger axes are at minimum value at rest */
if (axis_triggerleft >= 0) {
hwdata->axes[axis_triggerleft] = SDL_JOYSTICK_AXIS_MIN;
}
if (axis_triggerright >= 0) {
hwdata->axes[axis_triggerright] = SDL_JOYSTICK_AXIS_MIN;
}
}
if (hwdata->desc.nbuttons > 0) {
hwdata->buttons = SDL_calloc(hwdata->desc.nbuttons, sizeof(Uint8));
if (nbuttons > 0) {
hwdata->buttons = SDL_calloc(nbuttons, sizeof(Uint8));
if (!hwdata->buttons) {
VIRTUAL_FreeHWData(hwdata);
return SDL_OutOfMemory();
}
}
if (hwdata->desc.nhats > 0) {
hwdata->hats = SDL_calloc(hwdata->desc.nhats, sizeof(Uint8));
if (nhats > 0) {
hwdata->hats = SDL_calloc(nhats, sizeof(Uint8));
if (!hwdata->hats) {
VIRTUAL_FreeHWData(hwdata);
return SDL_OutOfMemory();
@@ -245,16 +138,8 @@ SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
hwdata->instance_id = SDL_GetNextJoystickInstanceID();
/* Add virtual joystick to SDL-global lists */
if (g_VJoys) {
joystick_hwdata *last;
for (last = g_VJoys; last->next; last = last->next) {
continue;
}
last->next = hwdata;
} else {
g_VJoys = hwdata;
}
hwdata->next = g_VJoys;
g_VJoys = hwdata;
SDL_PrivateJoystickAdded(hwdata->instance_id);
/* Return the new virtual-device's index */
@@ -291,7 +176,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value)
}
hwdata = (joystick_hwdata *)joystick->hwdata;
if (axis < 0 || axis >= hwdata->desc.naxes) {
if (axis < 0 || axis >= hwdata->naxes) {
SDL_UnlockJoysticks();
return SDL_SetError("Invalid axis index");
}
@@ -316,7 +201,7 @@ SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 valu
}
hwdata = (joystick_hwdata *)joystick->hwdata;
if (button < 0 || button >= hwdata->desc.nbuttons) {
if (button < 0 || button >= hwdata->nbuttons) {
SDL_UnlockJoysticks();
return SDL_SetError("Invalid button index");
}
@@ -341,7 +226,7 @@ SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value)
}
hwdata = (joystick_hwdata *)joystick->hwdata;
if (hat < 0 || hat >= hwdata->desc.nhats) {
if (hat < 0 || hat >= hwdata->nhats) {
SDL_UnlockJoysticks();
return SDL_SetError("Invalid hat index");
}
@@ -386,14 +271,7 @@ VIRTUAL_JoystickGetDeviceName(int device_index)
if (!hwdata) {
return NULL;
}
return hwdata->name;
}
static const char *
VIRTUAL_JoystickGetDevicePath(int device_index)
{
return NULL;
return hwdata->name ? hwdata->name : "";
}
@@ -407,11 +285,6 @@ VIRTUAL_JoystickGetDevicePlayerIndex(int device_index)
static void
VIRTUAL_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
if (hwdata && hwdata->desc.SetPlayerIndex) {
hwdata->desc.SetPlayerIndex(hwdata->desc.userdata, player_index);
}
}
@@ -446,12 +319,15 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
if (!hwdata) {
return SDL_SetError("No such device");
}
if (hwdata->opened) {
return SDL_SetError("Joystick already opened");
}
joystick->instance_id = hwdata->instance_id;
joystick->hwdata = hwdata;
joystick->naxes = hwdata->desc.naxes;
joystick->nbuttons = hwdata->desc.nbuttons;
joystick->nhats = hwdata->desc.nhats;
hwdata->joystick = joystick;
joystick->naxes = hwdata->naxes;
joystick->nbuttons = hwdata->nbuttons;
joystick->nhats = hwdata->nhats;
hwdata->opened = SDL_TRUE;
return 0;
}
@@ -459,99 +335,33 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index)
static int
VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
int result;
if (joystick->hwdata) {
joystick_hwdata *hwdata = joystick->hwdata;
if (hwdata->desc.Rumble) {
result = hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble);
} else {
result = SDL_Unsupported();
}
} else {
result = SDL_SetError("Rumble failed, device disconnected");
}
return result;
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
int result;
if (joystick->hwdata) {
joystick_hwdata *hwdata = joystick->hwdata;
if (hwdata->desc.RumbleTriggers) {
result = hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble);
} else {
result = SDL_Unsupported();
}
} else {
result = SDL_SetError("Rumble failed, device disconnected");
}
return result;
return SDL_Unsupported();
}
static Uint32
VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
{
joystick_hwdata *hwdata = joystick->hwdata;
Uint32 caps = 0;
if (hwdata) {
if (hwdata->desc.Rumble) {
caps |= SDL_JOYCAP_RUMBLE;
}
if (hwdata->desc.RumbleTriggers) {
caps |= SDL_JOYCAP_RUMBLE_TRIGGERS;
}
if (hwdata->desc.SetLED) {
caps |= SDL_JOYCAP_LED;
}
}
return caps;
return 0;
}
static int
VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
int result;
if (joystick->hwdata) {
joystick_hwdata *hwdata = joystick->hwdata;
if (hwdata->desc.SetLED) {
result = hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue);
} else {
result = SDL_Unsupported();
}
} else {
result = SDL_SetError("SetLED failed, device disconnected");
}
return result;
return SDL_Unsupported();
}
static int
VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
int result;
if (joystick->hwdata) {
joystick_hwdata *hwdata = joystick->hwdata;
if (hwdata->desc.SendEffect) {
result = hwdata->desc.SendEffect(hwdata->desc.userdata, data, size);
} else {
result = SDL_Unsupported();
}
} else {
result = SDL_SetError("SendEffect failed, device disconnected");
}
return result;
return SDL_Unsupported();
}
static int
@@ -576,17 +386,13 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
hwdata = (joystick_hwdata *)joystick->hwdata;
if (hwdata->desc.Update) {
hwdata->desc.Update(hwdata->desc.userdata);
}
for (i = 0; i < hwdata->desc.naxes; ++i) {
for (i = 0; i < hwdata->naxes; ++i) {
SDL_PrivateJoystickAxis(joystick, i, hwdata->axes[i]);
}
for (i = 0; i < hwdata->desc.nbuttons; ++i) {
for (i = 0; i < hwdata->nbuttons; ++i) {
SDL_PrivateJoystickButton(joystick, i, hwdata->buttons[i]);
}
for (i = 0; i < hwdata->desc.nhats; ++i) {
for (i = 0; i < hwdata->nhats; ++i) {
SDL_PrivateJoystickHat(joystick, i, hwdata->hats[i]);
}
}
@@ -595,11 +401,17 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick)
static void
VIRTUAL_JoystickClose(SDL_Joystick *joystick)
{
if (joystick->hwdata) {
joystick_hwdata *hwdata = joystick->hwdata;
hwdata->joystick = NULL;
joystick->hwdata = NULL;
joystick_hwdata *hwdata;
if (!joystick) {
return;
}
if (!joystick->hwdata) {
return;
}
hwdata = (joystick_hwdata *)joystick->hwdata;
hwdata->opened = SDL_FALSE;
}
@@ -614,145 +426,7 @@ VIRTUAL_JoystickQuit(void)
static SDL_bool
VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index);
int current_button = 0;
int current_axis = 0;
if (hwdata->desc.type != SDL_JOYSTICK_TYPE_GAMECONTROLLER) {
return SDL_FALSE;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_A))) {
out->a.kind = EMappingKind_Button;
out->a.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_B))) {
out->b.kind = EMappingKind_Button;
out->b.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_X))) {
out->x.kind = EMappingKind_Button;
out->x.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_Y))) {
out->y.kind = EMappingKind_Button;
out->y.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK))) {
out->back.kind = EMappingKind_Button;
out->back.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE))) {
out->guide.kind = EMappingKind_Button;
out->guide.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_START))) {
out->start.kind = EMappingKind_Button;
out->start.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK))) {
out->leftstick.kind = EMappingKind_Button;
out->leftstick.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK))) {
out->rightstick.kind = EMappingKind_Button;
out->rightstick.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER))) {
out->leftshoulder.kind = EMappingKind_Button;
out->leftshoulder.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))) {
out->rightshoulder.kind = EMappingKind_Button;
out->rightshoulder.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP))) {
out->dpup.kind = EMappingKind_Button;
out->dpup.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN))) {
out->dpdown.kind = EMappingKind_Button;
out->dpdown.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT))) {
out->dpleft.kind = EMappingKind_Button;
out->dpleft.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT))) {
out->dpright.kind = EMappingKind_Button;
out->dpright.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1))) {
out->misc1.kind = EMappingKind_Button;
out->misc1.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE1))) {
out->paddle1.kind = EMappingKind_Button;
out->paddle1.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE2))) {
out->paddle2.kind = EMappingKind_Button;
out->paddle2.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE3))) {
out->paddle3.kind = EMappingKind_Button;
out->paddle3.target = current_button++;
}
if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE4))) {
out->paddle4.kind = EMappingKind_Button;
out->paddle4.target = current_button++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX))) {
out->leftx.kind = EMappingKind_Axis;
out->leftx.target = current_axis++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY))) {
out->lefty.kind = EMappingKind_Axis;
out->lefty.target = current_axis++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX))) {
out->rightx.kind = EMappingKind_Axis;
out->rightx.target = current_axis++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY))) {
out->righty.kind = EMappingKind_Axis;
out->righty.target = current_axis++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT))) {
out->lefttrigger.kind = EMappingKind_Axis;
out->lefttrigger.target = current_axis++;
}
if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) {
out->righttrigger.kind = EMappingKind_Axis;
out->righttrigger.target = current_axis++;
}
return SDL_TRUE;
return SDL_FALSE;
}
SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
@@ -761,7 +435,6 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
VIRTUAL_JoystickGetCount,
VIRTUAL_JoystickDetect,
VIRTUAL_JoystickGetDeviceName,
VIRTUAL_JoystickGetDevicePath,
VIRTUAL_JoystickGetDevicePlayerIndex,
VIRTUAL_JoystickSetDevicePlayerIndex,
VIRTUAL_JoystickGetDeviceGUID,

View File

@@ -34,19 +34,24 @@ typedef struct joystick_hwdata
{
SDL_JoystickType type;
SDL_bool attached;
char *name;
const char *name;
SDL_JoystickGUID guid;
SDL_VirtualJoystickDesc desc;
int naxes;
Sint16 *axes;
int nbuttons;
Uint8 *buttons;
int nhats;
Uint8 *hats;
SDL_JoystickID instance_id;
SDL_Joystick *joystick;
SDL_bool opened;
struct joystick_hwdata *next;
} joystick_hwdata;
int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc);
int SDL_JoystickAttachVirtualInner(SDL_JoystickType type,
int naxes,
int nbuttons,
int nhats);
int SDL_JoystickDetachVirtualInner(int device_index);
int SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value);
@@ -54,7 +59,4 @@ int SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8
int SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value);
#endif /* SDL_JOYSTICK_VIRTUAL */
#endif /* SDL_VIRTUALJOYSTICK_C_H */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -147,7 +147,7 @@ int VITA_JoystickInit(void)
// after the app has already started.
SDL_numjoysticks = 1;
SDL_PrivateJoystickAdded(0);
// How many additional paired controllers are there?
sceCtrlGetControllerPortInfo(&myPortInfo);
@@ -157,7 +157,6 @@ int VITA_JoystickInit(void)
{
if (myPortInfo.port[i]!=SCE_CTRL_TYPE_UNPAIRED)
{
SDL_PrivateJoystickAdded(SDL_numjoysticks);
SDL_numjoysticks++;
}
}
@@ -179,6 +178,7 @@ SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index)
return device_index;
}
/* Function to get the device-dependent name of a joystick */
const char *VITA_JoystickGetDeviceName(int index)
{
if (index == 0)
@@ -194,12 +194,7 @@ const char *VITA_JoystickGetDeviceName(int index)
return "PSVita Controller";
SDL_SetError("No joystick available with that index");
return NULL;
}
const char *VITA_JoystickGetDevicePath(int index)
{
return NULL;
return(NULL);
}
static int
@@ -404,7 +399,6 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver =
VITA_JoystickGetCount,
VITA_JoystickDetect,
VITA_JoystickGetDeviceName,
VITA_JoystickGetDevicePath,
VITA_JoystickGetDevicePlayerIndex,
VITA_JoystickSetDevicePlayerIndex,
VITA_JoystickGetDeviceGUID,

View File

@@ -253,7 +253,7 @@ SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath)
return SDL_TRUE;
}
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor_id, product_id, NULL, SDL_FALSE);
type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);
if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
type == SDL_CONTROLLER_TYPE_XBOXONE ||
(vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) {
@@ -456,7 +456,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
pNewJoystick = *(JoyStick_DeviceData**)pContext;
while (pNewJoystick) {
/* update GUIDs of joysticks with matching paths, in case they're not open yet */
if (SDL_strcmp(pNewJoystick->path, hidPath) == 0) {
if (SDL_strcmp(pNewJoystick->hidPath, hidPath) == 0) {
/* if we are replacing the front of the list then update it */
if (pNewJoystick == *(JoyStick_DeviceData**)pContext) {
*(JoyStick_DeviceData**)pContext = pNewJoystick->pNext;
@@ -483,7 +483,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
CHECK(pNewJoystick);
SDL_zerop(pNewJoystick);
SDL_strlcpy(pNewJoystick->path, hidPath, SDL_arraysize(pNewJoystick->path));
SDL_strlcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath));
SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE));
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
@@ -683,7 +683,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext)
/* Sort using the data offset into the DInput struct.
* This gives a reasonable ordering for the inputs.
*/
static int SDLCALL
static int
SortDevFunc(const void *a, const void *b)
{
const input_t *inputA = (const input_t*)a;

View File

@@ -40,6 +40,7 @@
#include "SDL_timer.h"
#include "../usb_ids.h"
#include "../SDL_sysjoystick.h"
#include "../controller_type.h"
#include "../../core/windows/SDL_windows.h"
#include "../../core/windows/SDL_hid.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
@@ -61,18 +62,11 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
#define GamepadButtons_GUIDE 0x40000000
#define COBJMACROS
#include "windows.gaming.input.h"
#include <roapi.h>
#endif
#if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI)
#define SDL_JOYSTICK_RAWINPUT_MATCHING
#define SDL_JOYSTICK_RAWINPUT_MATCH_AXES
#define SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 6 // stick + trigger axes
#else
#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 4 // stick axes
#endif
#endif
/*#define DEBUG_RAWINPUT*/
@@ -104,7 +98,6 @@ typedef struct _SDL_RAWINPUT_Device
{
SDL_atomic_t refcount;
char *name;
char *path;
Uint16 vendor_id;
Uint16 product_id;
Uint16 version;
@@ -135,7 +128,7 @@ struct joystick_hwdata
USHORT trigger_hack_index;
#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
Uint64 match_state; /* Lowest 16 bits for button states, higher 24 for 6 4bit axes */
Uint32 match_state; /* Low 16 bits for button states, high 16 for 4 4bit axes */
Uint32 last_state_packet;
#endif
@@ -180,7 +173,7 @@ static struct {
typedef struct WindowsMatchState {
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
SHORT match_axes[SDL_JOYSTICK_RAWINPUT_MATCH_COUNT];
SHORT match_axes[4];
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
WORD xinput_buttons;
@@ -191,13 +184,13 @@ typedef struct WindowsMatchState {
SDL_bool any_data;
} WindowsMatchState;
static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state)
static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint32 match_state)
{
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
int ii;
#endif
SDL_bool any_axes_data = SDL_FALSE;
state->any_data = SDL_FALSE;
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
/* SHORT state->match_axes[4] = {
(match_state & 0x000F0000) >> 4,
@@ -206,18 +199,12 @@ static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state
(match_state & 0xF0000000) >> 16,
}; */
for (ii = 0; ii < 4; ii++) {
state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4));
any_axes_data |= ((Uint32)(state->match_axes[ii] + 0x1000) > 0x2000); /* match_state bit is not 0xF, 0x1, or 0x2 */
state->match_axes[ii] = (match_state & (0x000F0000 << (ii * 4))) >> (4 + ii * 4);
if ((Uint32)(state->match_axes[ii] + 0x1000) > 0x2000) { /* match_state bit is not 0xF, 0x1, or 0x2 */
state->any_data = SDL_TRUE;
}
}
#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_AXES */
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
for (; ii < SDL_JOYSTICK_RAWINPUT_MATCH_COUNT; ii++) {
state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4));
any_axes_data |= (state->match_axes[ii] != SDL_MIN_SINT16);
}
#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */
state->any_data = any_axes_data;
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
/* Match axes by checking if the distance between the high 4 bits of axis and the 4 bits from match_state is 1 or less */
@@ -233,16 +220,9 @@ static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state
SDL_abs((Sint8)((gamepad.sThumbRX & 0xF000) >> 8) - ((match_state & 0x0F000000) >> 20)) <= 0x10 && \
SDL_abs((Sint8)((~gamepad.sThumbRY & 0xF000) >> 8) - ((match_state & 0xF0000000) >> 24)) <= 0x10) */
/* Can only match trigger values if a single trigger has a value. */
#define XInputTriggersMatch(gamepad) ( \
((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \
((gamepad.bLeftTrigger != 0) && (gamepad.bRightTrigger != 0)) || \
((Uint32)((((int)gamepad.bLeftTrigger * 257) - 32768) - state->match_axes[4]) <= 0x2fff) || \
((Uint32)((((int)gamepad.bRightTrigger * 257) - 32768) - state->match_axes[5]) <= 0x2fff))
state->xinput_buttons =
/* Bitwise map .RLDUWVQTS.KYXBA -> YXBA..WVQTKSRLDU */
(WORD)(match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11);
match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11;
/* Explicit
((match_state & (1<<SDL_CONTROLLER_BUTTON_A)) ? XINPUT_GAMEPAD_A : 0) |
((match_state & (1<<SDL_CONTROLLER_BUTTON_B)) ? XINPUT_GAMEPAD_B : 0) |
@@ -272,11 +252,6 @@ static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state
(Uint16)(((Sint16)(gamepad.RightThumbstickX * SDL_MAX_SINT16) & 0xF000) - state->match_axes[2] + 0x1000) <= 0x2fff && \
(Uint16)((~(Sint16)(gamepad.RightThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[3] + 0x1000) <= 0x2fff)
#define WindowsGamingInputTriggersMatch(gamepad) ( \
((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \
((gamepad.LeftTrigger == 0.0f) && (gamepad.RightTrigger == 0.0f)) || \
((Uint16)((((int)(gamepad.LeftTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[4]) <= 0x2fff) || \
((Uint16)((((int)(gamepad.RightTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[5]) <= 0x2fff))
state->wgi_buttons =
/* Bitwise map .RLD UWVQ TS.K YXBA -> ..QT WVRL DUYX BAKS */
@@ -379,9 +354,6 @@ RAWINPUT_XInputSlotMatches(const WindowsMatchState *state, Uint8 slot_idx)
if ((xinput_buttons & ~XINPUT_GAMEPAD_GUIDE) == state->xinput_buttons
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
&& XInputAxesMatch(xinput_state[slot_idx].state.Gamepad)
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
&& XInputTriggersMatch(xinput_state[slot_idx].state.Gamepad)
#endif
) {
return SDL_TRUE;
@@ -566,24 +538,22 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
if (!wgi_state.initialized) {
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
HRESULT hr;
HMODULE hModule;
if (FAILED(WIN_RoInitialize())) {
/* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */
if (FAILED(WIN_CoInitialize())) {
return;
}
wgi_state.initialized = SDL_TRUE;
wgi_state.dirty = SDL_TRUE;
{
hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) {
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
#ifdef __WINRT__
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
#endif
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
HSTRING_HEADER hNamespaceStringHeader;
@@ -594,21 +564,18 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
}
}
FreeLibrary(hModule);
}
}
}
static SDL_bool
RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGamingInputGamepadState *slot, SDL_bool xinput_correlated)
RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGamingInputGamepadState *slot)
{
Uint32 wgi_buttons = slot->state.Buttons;
if ((wgi_buttons & 0x3FFF) == state->wgi_buttons
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
&& WindowsGamingInputAxesMatch(slot->state)
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
// Don't try to match WGI triggers if getting values from XInput
&& (xinput_correlated || WindowsGamingInputTriggersMatch(slot->state))
#endif
) {
return SDL_TRUE;
@@ -617,14 +584,14 @@ RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGa
}
static SDL_bool
RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot, SDL_bool xinput_correlated)
RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot)
{
int match_count, user_index;
match_count = 0;
for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) {
WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[user_index];
if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state, xinput_correlated)) {
if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state)) {
++match_count;
*slot = gamepad_state;
/* Incrementing correlation_id for any match, as negative evidence for others being correlated */
@@ -659,7 +626,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
wgi_state.gamepad_statics = NULL;
}
WIN_RoUninitialize();
WIN_CoUninitialize();
wgi_state.initialized = SDL_FALSE;
}
}
@@ -689,9 +656,10 @@ RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *device)
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
if (SDL_AtomicDecRef(&device->refcount)) {
SDL_free(device->preparsed_data);
if (device->preparsed_data) {
SDL_HidD_FreePreparsedData(device->preparsed_data);
}
SDL_free(device->name);
SDL_free(device->path);
SDL_free(device);
}
}
@@ -715,8 +683,9 @@ RAWINPUT_AddDevice(HANDLE hDevice)
SDL_RAWINPUT_Device *device = NULL;
SDL_RAWINPUT_Device *curr, *last;
RID_DEVICE_INFO rdi;
UINT size;
UINT rdi_size = sizeof(rdi);
char dev_name[MAX_PATH];
UINT name_size = SDL_arraysize(dev_name);
HANDLE hFile = INVALID_HANDLE_VALUE;
/* Make sure we're not trying to add the same device twice */
@@ -725,13 +694,11 @@ RAWINPUT_AddDevice(HANDLE hDevice)
}
/* Figure out what kind of device it is */
size = sizeof(rdi);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &size) != (UINT)-1);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1);
CHECK(rdi.dwType == RIM_TYPEHID);
/* Get the device "name" (HID Path) */
size = SDL_arraysize(dev_name);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1);
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1);
/* Only take XInput-capable devices */
CHECK(SDL_strstr(dev_name, "IG_") != NULL);
#ifdef SDL_JOYSTICK_HIDAPI
@@ -745,13 +712,7 @@ RAWINPUT_AddDevice(HANDLE hDevice)
device->product_id = (Uint16)rdi.hid.dwProductId;
device->version = (Uint16)rdi.hid.dwVersionNumber;
device->is_xinput = SDL_TRUE;
device->is_xboxone = SDL_IsJoystickXboxOne(device->vendor_id, device->product_id);
/* Get HID Top-Level Collection Preparsed Data */
size = 0;
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, NULL, &size) != (UINT)-1);
CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)));
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1);
device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController;
{
const Uint16 vendor = device->vendor_id;
@@ -797,7 +758,8 @@ RAWINPUT_AddDevice(HANDLE hDevice)
SDL_free(product_string);
}
}
device->path = SDL_strdup(dev_name);
CHECK(SDL_HidD_GetPreparsedData(hFile, &device->preparsed_data));
CloseHandle(hFile);
hFile = INVALID_HANDLE_VALUE;
@@ -830,12 +792,8 @@ err:
CloseHandle(hFile);
}
if (device) {
if (device->name) {
if (device->name)
SDL_free(device->name);
}
if (device->path) {
SDL_free(device->path);
}
SDL_free(device);
}
#undef CHECK
@@ -932,12 +890,9 @@ RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, co
return SDL_TRUE;
}
/* The Xbox 360 wireless controller shows up as product 0 in WGI.
Try to match it to a Raw Input device via name or known product ID. */
/* The Xbox 360 wireless controller shows up as product 0 in WGI */
if (vendor_id == device->vendor_id && product_id == 0 &&
((name && SDL_strstr(device->name, name) != NULL) ||
(device->vendor_id == USB_VENDOR_MICROSOFT &&
device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) {
name && SDL_strstr(device->name, name) != NULL) {
return SDL_TRUE;
}
@@ -1038,12 +993,6 @@ RAWINPUT_JoystickGetDeviceName(int device_index)
return RAWINPUT_GetDeviceByIndex(device_index)->name;
}
static const char *
RAWINPUT_JoystickGetDevicePath(int device_index)
{
return RAWINPUT_GetDeviceByIndex(device_index)->path;
}
static int
RAWINPUT_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -1068,7 +1017,7 @@ RAWINPUT_JoystickGetDeviceInstanceID(int device_index)
return RAWINPUT_GetDeviceByIndex(device_index)->joystick_id;
}
static int SDLCALL
static int
RAWINPUT_SortValueCaps(const void *A, const void *B)
{
HIDP_VALUE_CAPS *capsA = (HIDP_VALUE_CAPS *)A;
@@ -1268,7 +1217,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
}
}
joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_UNKNOWN);
return 0;
}
@@ -1278,8 +1227,8 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin
{
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
#endif
SDL_bool rumbled = SDL_FALSE;
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
if (!rumbled && ctx->wgi_correlated) {
@@ -1312,13 +1261,6 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin
}
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
if (!rumbled) {
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
#else
return SDL_Unsupported();
#endif
}
return 0;
}
@@ -1327,7 +1269,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
{
#if defined(SDL_JOYSTICK_RAWINPUT_WGI)
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
if (ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr;
@@ -1337,10 +1279,8 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
if (!SUCCEEDED(hr)) {
return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
}
return 0;
} else {
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
}
return 0;
#else
return SDL_Unsupported();
#endif
@@ -1349,15 +1289,15 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
static Uint32
RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick)
{
Uint32 result = 0;
#if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI)
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
Uint32 result = 0;
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
if (ctx->is_xinput) {
result |= SDL_JOYCAP_RUMBLE;
}
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
if (ctx->is_xinput) {
result |= SDL_JOYCAP_RUMBLE;
@@ -1367,7 +1307,6 @@ RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick)
}
}
#endif
#endif /**/
return result;
}
@@ -1444,13 +1383,12 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size)
(1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT),
(1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT),
};
Uint64 match_state = ctx->match_state;
Uint32 match_state = ctx->match_state;
/* Update match_state with button bit, then fall through */
#define SDL_PrivateJoystickButton(joystick, button, state) if (button < SDL_arraysize(button_map)) { Uint64 button_bit = 1ull << button_map[button]; match_state = (match_state & ~button_bit) | (button_bit * (state)); } SDL_PrivateJoystickButton(joystick, button, state)
#define SDL_PrivateJoystickButton(joystick, button, state) if (button < SDL_arraysize(button_map)) { if (state) match_state |= 1 << button_map[button]; else match_state &= ~(1 << button_map[button]); } SDL_PrivateJoystickButton(joystick, button, state)
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES
/* Grab high 4 bits of value, then fall through */
#define AddAxisToMatchState(axis, value) { match_state = (match_state & ~(0xFull << (4 * axis + 16))) | ((value) & 0xF000ull) << (4 * axis + 4); }
#define SDL_PrivateJoystickAxis(joystick, axis, value) if (axis < 4) AddAxisToMatchState(axis, value); SDL_PrivateJoystickAxis(joystick, axis, value)
#define SDL_PrivateJoystickAxis(joystick, axis, value) if (axis < 4) match_state = (match_state & ~(0xF << (4 * axis + 16))) | ((value) & 0xF000) << (4 * axis + 4); SDL_PrivateJoystickAxis(joystick, axis, value)
#endif
#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */
@@ -1515,14 +1453,8 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size)
#undef SDL_PrivateJoystickAxis
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
#define AddTriggerToMatchState(axis, value) { int match_axis = axis + SDL_JOYSTICK_RAWINPUT_MATCH_COUNT - joystick->naxes; AddAxisToMatchState(match_axis, value); }
#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */
if (ctx->trigger_hack) {
SDL_bool has_trigger_data = SDL_FALSE;
int left_trigger = joystick->naxes - 2;
int right_trigger = joystick->naxes - 1;
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
/* Prefer XInput over WindowsGamingInput, it continues to provide data in the background */
@@ -1537,36 +1469,28 @@ RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size)
}
#endif /* SDL_JOYSTICK_RAWINPUT_WGI */
#ifndef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
if (!has_trigger_data)
#endif
{
if (!has_trigger_data) {
HIDP_DATA *item = GetData(ctx->trigger_hack_index, ctx->data, data_length);
if (item) {
int left_trigger = joystick->naxes - 2;
int right_trigger = joystick->naxes - 1;
Sint16 value = (int)(Uint16)item->RawValue - 0x8000;
Sint16 left_value = (value > 0) ? (value * 2 - 32767) : SDL_MIN_SINT16;
Sint16 right_value = (value < 0) ? (-value * 2 - 32769) : SDL_MIN_SINT16;
#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS
AddTriggerToMatchState(left_trigger, left_value);
AddTriggerToMatchState(right_trigger, right_value);
if (!has_trigger_data)
#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */
{
SDL_PrivateJoystickAxis(joystick, left_trigger, left_value);
SDL_PrivateJoystickAxis(joystick, right_trigger, right_value);
if (value < 0) {
value = -value * 2 - 32769;
SDL_PrivateJoystickAxis(joystick, left_trigger, SDL_MIN_SINT16);
SDL_PrivateJoystickAxis(joystick, right_trigger, value);
} else if (value > 0) {
value = value * 2 - 32767;
SDL_PrivateJoystickAxis(joystick, left_trigger, value);
SDL_PrivateJoystickAxis(joystick, right_trigger, SDL_MIN_SINT16);
} else {
SDL_PrivateJoystickAxis(joystick, left_trigger, SDL_MIN_SINT16);
SDL_PrivateJoystickAxis(joystick, right_trigger, SDL_MIN_SINT16);
}
}
}
}
#ifdef AddAxisToMatchState
#undef AddAxisToMatchState
#endif
#ifdef AddTriggerToMatchState
#undef AddTriggerToMatchState
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING
if (ctx->is_xinput) {
ctx->match_state = match_state;
@@ -1586,25 +1510,17 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
int guide_button = joystick->nbuttons - 1;
int left_trigger = joystick->naxes - 2;
int right_trigger = joystick->naxes - 1;
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
SDL_bool xinput_correlated;
#endif
RAWINPUT_FillMatchState(&match_state_xinput, ctx->match_state);
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
xinput_correlated = ctx->xinput_correlated;
#else
xinput_correlated = SDL_FALSE;
#endif
/* Parallel logic to WINDOWS_XINPUT below */
RAWINPUT_UpdateWindowsGamingInput();
if (ctx->wgi_correlated &&
!joystick->low_frequency_rumble && !joystick->high_frequency_rumble &&
!joystick->left_trigger_rumble && !joystick->right_trigger_rumble) {
/* We have been previously correlated, ensure we are still matching, see comments in XINPUT section */
if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, xinput_correlated)) {
if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot)) {
ctx->wgi_uncorrelate_count = 0;
} else {
++ctx->wgi_uncorrelate_count;
@@ -1633,7 +1549,7 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
if (RAWINPUT_MissingWindowsGamingInputSlot()) {
Uint8 correlation_id;
WindowsGamingInputGamepadState *slot_idx = NULL;
if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, xinput_correlated)) {
if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx)) {
/* we match exactly one WindowsGamingInput device */
/* Probably can do without wgi_correlation_count, just check and clear wgi_slot to NULL, unless we need
even more frames to be sure. */
@@ -1935,7 +1851,7 @@ RAWINPUT_UnregisterNotifications()
return;
}
}
LRESULT CALLBACK
RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -2030,7 +1946,6 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
RAWINPUT_JoystickGetCount,
RAWINPUT_JoystickDetect,
RAWINPUT_JoystickGetDeviceName,
RAWINPUT_JoystickGetDevicePath,
RAWINPUT_JoystickGetDevicePlayerIndex,
RAWINPUT_JoystickSetDevicePlayerIndex,
RAWINPUT_JoystickGetDeviceGUID,

View File

@@ -35,13 +35,6 @@
#include <roapi.h>
#ifdef ____FIReference_1_INT32_INTERFACE_DEFINED__
/* MinGW-64 uses __FIReference_1_INT32 instead of Microsoft's __FIReference_1_int */
#define __FIReference_1_int __FIReference_1_INT32
#define __FIReference_1_int_get_Value __FIReference_1_INT32_get_Value
#define __FIReference_1_int_Release __FIReference_1_INT32_Release
#endif
struct joystick_hwdata
{
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller;
@@ -75,7 +68,6 @@ static struct {
EventRegistrationToken controller_added_token;
EventRegistrationToken controller_removed_token;
int controller_count;
SDL_bool ro_initialized;
WindowsGamingInputControllerState *controllers;
} wgi;
@@ -268,9 +260,10 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
WindowsDeleteStringFunc = WindowsDeleteString;
#else
{
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer");
WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString");
HMODULE hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) {
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
}
#endif /* __WINRT__ */
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
@@ -284,10 +277,15 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
WindowsDeleteStringFunc(hString);
}
}
#ifndef __WINRT__
if (hModule != NULL) {
FreeLibrary(hModule);
}
#endif
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
}
if (!name) {
name = SDL_strdup("");
name = "";
}
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller);
@@ -446,43 +444,23 @@ WGI_JoystickInit(void)
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
#ifndef __WINRT__
HMODULE hModule;
#endif
HRESULT hr;
if (FAILED(WIN_RoInitialize())) {
return SDL_SetError("RoInitialize() failed");
if (FAILED(WIN_CoInitialize())) {
return SDL_SetError("CoInitialize() failed");
}
wgi.ro_initialized = SDL_TRUE;
#ifndef __WINRT__
{
/* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself.
* This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing.
* As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later.
* See https://github.com/libsdl-org/SDL/issues/5552 for more details.
*/
static PVOID cookie = NULL;
if (!cookie) {
typedef HRESULT (WINAPI *CoIncrementMTAUsage_t)(PVOID* pCookie);
CoIncrementMTAUsage_t CoIncrementMTAUsageFunc = (CoIncrementMTAUsage_t)WIN_LoadComBaseFunction("CoIncrementMTAUsage");
if (CoIncrementMTAUsageFunc) {
if (FAILED(CoIncrementMTAUsageFunc(&cookie))) {
return SDL_SetError("CoIncrementMTAUsage() failed");
}
} else {
/* CoIncrementMTAUsage() is present since Win8, so we should never make it here. */
return SDL_SetError("CoIncrementMTAUsage() not found");
}
}
}
#endif
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
{
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) {
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
}
#endif /* __WINRT__ */
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
@@ -541,6 +519,11 @@ WGI_JoystickInit(void)
}
}
}
#ifndef __WINRT__
if (hModule != NULL) {
FreeLibrary(hModule);
}
#endif
if (wgi.statics) {
__FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers;
@@ -593,12 +576,6 @@ WGI_JoystickGetDeviceName(int device_index)
return wgi.controllers[device_index].name;
}
static const char *
WGI_JoystickGetDevicePath(int device_index)
{
return NULL;
}
static int
WGI_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -886,12 +863,53 @@ WGI_JoystickQuit(void)
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerRemoved(wgi.statics, wgi.controller_removed_token);
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.statics);
}
if (wgi.ro_initialized) {
WIN_RoUninitialize();
}
SDL_zero(wgi);
/* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting.
*
* If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize()
* with this stack trace:
Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown
Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerPrivate>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass<struct Windows::Gaming::Input::IGamepad,struct Windows::Gaming::Input::IGamepad2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGipGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IHidGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IXusbGameControllerInputSink>,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::~GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Foundation::Collections::IIterable<class Windows::Gaming::Input::ArcadeStick *>,struct Windows::Foundation::Collections::IVectorView<class Windows::Gaming::Input::ArcadeStick *>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::~CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>(void) Unknown
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::ICustomGameControllerFactory> >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
Windows.Gaming.Input.dll!NtList<struct FactoryManager::FactoryListEntry>::~NtList<struct FactoryManager::FactoryListEntry>(void) Unknown
Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics>,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerFactoryManagerStaticsPrivate>,0>::Release(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown
Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown
Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage<Microsoft::WRL::Details::DefaultModule<1>,0,int>::instance_''() Unknown
Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown
Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown
ntdll.dll!_LdrxCallInitRoutine@16() Unknown
ntdll.dll!LdrpCallInitRoutine() Unknown
ntdll.dll!LdrpProcessDetachNode() Unknown
ntdll.dll!LdrpUnloadNode() Unknown
ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown
ntdll.dll!LdrUnloadDll() Unknown
KernelBase.dll!FreeLibrary() Unknown
combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++
combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++
combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++
combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++
[Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++
combase.dll!ProcessUninitialize() Line 2243 C++
combase.dll!DecrementProcessInitializeCount() Line 993 C++
combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++
combase.dll!CoUninitialize() Line 3945 C++
*/
/* WIN_CoUninitialize(); */
}
static SDL_bool
@@ -906,7 +924,6 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver =
WGI_JoystickGetCount,
WGI_JoystickDetect,
WGI_JoystickGetDeviceName,
WGI_JoystickGetDevicePath,
WGI_JoystickGetDevicePlayerIndex,
WGI_JoystickSetDevicePlayerIndex,
WGI_JoystickGetDeviceGUID,

View File

@@ -330,7 +330,7 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
static SDL_DeviceNotificationData s_notification_data;
/* Function/thread to scan the system for joysticks. */
static int SDLCALL
static int
SDL_JoystickThread(void *_data)
{
#if SDL_JOYSTICK_XINPUT
@@ -555,6 +555,7 @@ WINDOWS_JoystickDetect(void)
}
}
/* Function to get the device-dependent name of a joystick */
static const char *
WINDOWS_JoystickGetDeviceName(int device_index)
{
@@ -567,18 +568,6 @@ WINDOWS_JoystickGetDeviceName(int device_index)
return device->joystickname;
}
static const char *
WINDOWS_JoystickGetDevicePath(int device_index)
{
JoyStick_DeviceData *device = SYS_Joystick;
int index;
for (index = device_index; index > 0; index--)
device = device->pNext;
return device->path;
}
static int
WINDOWS_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -766,7 +755,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetCount,
WINDOWS_JoystickDetect,
WINDOWS_JoystickGetDeviceName,
WINDOWS_JoystickGetDevicePath,
WINDOWS_JoystickGetDevicePlayerIndex,
WINDOWS_JoystickSetDevicePlayerIndex,
WINDOWS_JoystickGetDeviceGUID,

View File

@@ -37,7 +37,7 @@ typedef struct JoyStick_DeviceData
BYTE SubType;
Uint8 XInputUserId;
DIDEVICEINSTANCE dxdevice;
char path[MAX_PATH];
char hidPath[MAX_PATH];
struct JoyStick_DeviceData *pNext;
} JoyStick_DeviceData;

View File

@@ -201,20 +201,9 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
* userid, but we'll record it so we'll at least be consistent
* when the raw device list changes.
*/
if (rdi.hid.dwVendorId == USB_VENDOR_VALVE &&
rdi.hid.dwProductId == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) {
/* Steam encodes the real device in the path */
int realVID = rdi.hid.dwVendorId;
int realPID = rdi.hid.dwProductId;
SDL_sscanf(devName, "\\\\.\\pipe\\HID#VID_045E&PID_028E&IG_00#%x&%x&", &realVID, &realPID);
*pVID = (Uint16)realVID;
*pPID = (Uint16)realPID;
*pVersion = 0;
} else {
*pVID = (Uint16)rdi.hid.dwVendorId;
*pPID = (Uint16)rdi.hid.dwProductId;
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
}
*pVID = (Uint16)rdi.hid.dwVendorId;
*pPID = (Uint16)rdi.hid.dwProductId;
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
if (s_arrXInputDevicePath[userid]) {
SDL_free(s_arrXInputDevicePath[userid]);
}
@@ -297,7 +286,6 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
SDL_free(pNewJoystick);
return; /* better luck next time? */
}
SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid);
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
SDL_free(pNewJoystick);