early-access version 2281
This commit is contained in:
122
externals/SDL/src/joystick/SDL_gamecontroller.c
vendored
122
externals/SDL/src/joystick/SDL_gamecontroller.c
vendored
@@ -1515,6 +1515,57 @@ SDL_GameControllerNumMappings(void)
|
||||
return num_mappings;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a mapping string for a mapping
|
||||
*/
|
||||
static char *
|
||||
CreateMappingString(ControllerMapping_t *mapping, SDL_JoystickGUID guid)
|
||||
{
|
||||
char *pMappingString, *pPlatformString;
|
||||
char pchGUID[33];
|
||||
size_t needed;
|
||||
const char *platform = SDL_GetPlatform();
|
||||
|
||||
SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
|
||||
|
||||
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
|
||||
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
|
||||
|
||||
if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) {
|
||||
/* add memory for ',' + platform:PLATFORM */
|
||||
if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') {
|
||||
needed += 1;
|
||||
}
|
||||
needed += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD) + SDL_strlen(platform);
|
||||
}
|
||||
|
||||
pMappingString = SDL_malloc(needed);
|
||||
if (!pMappingString) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
|
||||
|
||||
if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) {
|
||||
if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') {
|
||||
SDL_strlcat(pMappingString, ",", needed);
|
||||
}
|
||||
SDL_strlcat(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD, needed);
|
||||
SDL_strlcat(pMappingString, platform, needed);
|
||||
}
|
||||
|
||||
/* Make sure multiple platform strings haven't made their way into the mapping */
|
||||
pPlatformString = SDL_strstr(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD);
|
||||
if (pPlatformString) {
|
||||
pPlatformString = SDL_strstr(pPlatformString + 1, SDL_CONTROLLER_PLATFORM_FIELD);
|
||||
if (pPlatformString) {
|
||||
*pPlatformString = '\0';
|
||||
}
|
||||
}
|
||||
return pMappingString;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mapping at a particular index.
|
||||
*/
|
||||
@@ -1528,20 +1579,7 @@ SDL_GameControllerMappingForIndex(int mapping_index)
|
||||
continue;
|
||||
}
|
||||
if (mapping_index == 0) {
|
||||
char *pMappingString;
|
||||
char pchGUID[33];
|
||||
size_t needed;
|
||||
|
||||
SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
|
||||
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
|
||||
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
|
||||
pMappingString = SDL_malloc(needed);
|
||||
if (!pMappingString) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
|
||||
return pMappingString;
|
||||
return CreateMappingString(mapping, mapping->guid);
|
||||
}
|
||||
--mapping_index;
|
||||
}
|
||||
@@ -1554,22 +1592,11 @@ SDL_GameControllerMappingForIndex(int mapping_index)
|
||||
char *
|
||||
SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
|
||||
{
|
||||
char *pMappingString = NULL;
|
||||
ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE);
|
||||
if (mapping) {
|
||||
char pchGUID[33];
|
||||
size_t needed;
|
||||
SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
|
||||
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
|
||||
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
|
||||
pMappingString = SDL_malloc(needed);
|
||||
if (!pMappingString) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
|
||||
return CreateMappingString(mapping, guid);
|
||||
}
|
||||
return pMappingString;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1793,6 +1820,13 @@ 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) {
|
||||
return SDL_FALSE;
|
||||
@@ -2447,6 +2481,18 @@ SDL_GameControllerHasLED(SDL_GameController *gamecontroller)
|
||||
return SDL_JoystickHasLED(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_GameControllerHasRumble(SDL_GameController *gamecontroller)
|
||||
{
|
||||
return SDL_JoystickHasRumble(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller)
|
||||
{
|
||||
return SDL_JoystickHasRumbleTriggers(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
@@ -2675,4 +2721,26 @@ SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
|
||||
{
|
||||
#if defined(SDL_JOYSTICK_MFI)
|
||||
const char *IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button);
|
||||
return IOS_GameControllerGetAppleSFSymbolsNameForButton(gamecontroller, button);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
|
||||
{
|
||||
#if defined(SDL_JOYSTICK_MFI)
|
||||
const char *IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis);
|
||||
return IOS_GameControllerGetAppleSFSymbolsNameForAxis(gamecontroller, axis);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
@@ -26,7 +26,7 @@
|
||||
The easiest way to generate a new mapping is to start Steam in Big Picture
|
||||
mode, configure your joystick and then look in config/config.vdf in your
|
||||
Steam installation directory for the "SDL_GamepadBind" entry.
|
||||
|
||||
|
||||
Alternatively, you can use the app located in test/controllermap
|
||||
*/
|
||||
static const char *s_ControllerMappings [] =
|
||||
@@ -135,7 +135,7 @@ static const char *s_ControllerMappings [] =
|
||||
"78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,",
|
||||
"03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,",
|
||||
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,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:a4,start:b9,x:b3,y:b0,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,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:b3,y:b0,",
|
||||
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,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,",
|
||||
"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,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:a3,righty:a2,start:b9,x:b3,y:b0,",
|
||||
"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,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:b3,y:b0,",
|
||||
@@ -248,7 +248,7 @@ static const char *s_ControllerMappings [] =
|
||||
"030000003807000056a8000000000000,PS3 RF pad,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,",
|
||||
"03000000100000008200000000000000,PS360+ v1.66,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:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"030000004c050000a00b000000000000,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,",
|
||||
"030000004c050000c405000000000000,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,",
|
||||
"030000004c050000c405000000000000,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,touchpad:b13,x:b0,y:b3,",
|
||||
"030000004c050000cc09000000000000,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,",
|
||||
"030000004c050000e60c000000000000,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,",
|
||||
@@ -396,7 +396,7 @@ static const char *s_ControllerMappings [] =
|
||||
"030000000d0f00008500000000010000,Fighting Commander,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,",
|
||||
"03000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle3:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,",
|
||||
"03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,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:a3,righty:a4,start:b9,x:b3,y:b0,",
|
||||
"03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,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:b3,y:b0,",
|
||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,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:b2,y:b3,",
|
||||
"03000000c01100000140000000010000,GameStop PS4 Fun 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,",
|
||||
"03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,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,",
|
||||
@@ -482,6 +482,7 @@ static const char *s_ControllerMappings [] =
|
||||
"030000005e040000d102000000000000,Xbox One Wired Controller,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,",
|
||||
"030000005e040000dd02000000000000,Xbox One Wired Controller,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,",
|
||||
"030000005e040000e302000000000000,Xbox One Wired Controller,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,",
|
||||
"030000005e040000200b000011050000,Xbox Wireless 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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"030000005e040000e002000000000000,Xbox 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,",
|
||||
"030000005e040000e002000003090000,Xbox 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,",
|
||||
"030000005e040000ea02000000000000,Xbox Wireless Controller,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,",
|
||||
@@ -556,8 +557,9 @@ static const char *s_ControllerMappings [] =
|
||||
"03000000790000003018000011010000,Arcade Fightstick F300,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,start:b9,x:b0,y:b3,",
|
||||
"03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,",
|
||||
"05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,",
|
||||
"03000000503200000210000000000000,Atari Game 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:b3,y:b2,",
|
||||
"03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,",
|
||||
"05000000503200000210000000000000,Atari Game 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:b3,y:b2,",
|
||||
"030000005e0400008e02000047010000,Atari Xbox 360 Game 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,",
|
||||
"03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,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,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"03000000d62000002a79000011010000,BDA PS4 Fightpad,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,",
|
||||
"03000000120c0000f70e000011010000,Brook Universal Fighting Board,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:,lefty:,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:,righty:,start:b9,x:b0,y:b3,",
|
||||
@@ -589,6 +591,7 @@ static const char *s_ControllerMappings [] =
|
||||
"030000000d0f00002200000011010000,HORI CO. LTD. 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,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,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,",
|
||||
"030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,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,",
|
||||
"030000000d0f00005001000009040000,HORI Fighting Commander OCTA,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,",
|
||||
"030000000d0f00008400000011010000,HORI Fighting Commander,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,",
|
||||
"030000000d0f00008500000010010000,HORI Fighting Commander,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,",
|
||||
"030000000d0f0000d800000072056800,HORI Real Arcade Pro S,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,",
|
||||
@@ -695,8 +698,9 @@ static const char *s_ControllerMappings [] =
|
||||
"050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
|
||||
"030000004c050000e60c000000010000,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,",
|
||||
"030000004c050000e60c000011010000,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,",
|
||||
"030000004c050000e60c000011810000,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,",
|
||||
"030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
|
||||
"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,",
|
||||
"050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
|
||||
"030000004c050000da0c000011010000,Playstation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,",
|
||||
"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,",
|
||||
|
92
externals/SDL/src/joystick/SDL_joystick.c
vendored
92
externals/SDL/src/joystick/SDL_joystick.c
vendored
@@ -343,6 +343,9 @@ SDL_JoystickGetDevicePlayerIndex(int device_index)
|
||||
static SDL_bool
|
||||
SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
|
||||
{
|
||||
#ifdef __WINRT__
|
||||
return SDL_TRUE;
|
||||
#else
|
||||
static Uint32 zero_centered_joysticks[] = {
|
||||
MAKE_VIDPID(0x0e8f, 0x3013), /* HuiJia SNES USB adapter */
|
||||
MAKE_VIDPID(0x05a0, 0x3232), /* 8Bitdo Zero Gamepad */
|
||||
@@ -365,6 +368,7 @@ SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick)
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
#endif /* __WINRT__ */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -759,7 +763,7 @@ SDL_JoystickGetButton(SDL_Joystick *joystick, int button)
|
||||
SDL_bool
|
||||
SDL_JoystickGetAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
if (!joystick) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -944,7 +948,43 @@ SDL_JoystickHasLED(SDL_Joystick *joystick)
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
result = joystick->driver->HasLED(joystick);
|
||||
result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_LED) != 0;
|
||||
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_JoystickHasRumble(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_bool result;
|
||||
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE) != 0;
|
||||
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_bool result;
|
||||
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
result = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE_TRIGGERS) != 0;
|
||||
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
@@ -1095,8 +1135,8 @@ SDL_JoystickQuit(void)
|
||||
SDL_JoystickClose(SDL_joysticks);
|
||||
}
|
||||
|
||||
/* Quit the joystick setup */
|
||||
for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
|
||||
/* Quit drivers in reverse order to avoid breaking dependencies between drivers */
|
||||
for (i = SDL_arraysize(SDL_joystick_drivers) - 1; i >= 0; --i) {
|
||||
SDL_joystick_drivers[i]->Quit();
|
||||
}
|
||||
|
||||
@@ -1344,7 +1384,7 @@ SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
|
||||
info->value = value;
|
||||
info->zero = value;
|
||||
info->has_initial_value = SDL_TRUE;
|
||||
} else if (value == info->value) {
|
||||
} else if (value == info->value && !info->sending_initial_value) {
|
||||
return 0;
|
||||
} else {
|
||||
info->has_second_value = SDL_TRUE;
|
||||
@@ -1356,15 +1396,17 @@ SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
|
||||
return 0;
|
||||
}
|
||||
info->sent_initial_value = SDL_TRUE;
|
||||
info->value = ~value; /* Just so we pass the check above */
|
||||
info->sending_initial_value = SDL_TRUE;
|
||||
SDL_PrivateJoystickAxis(joystick, axis, info->initial_value);
|
||||
info->sending_initial_value = SDL_FALSE;
|
||||
}
|
||||
|
||||
/* We ignore events if we don't have keyboard focus, except for centering
|
||||
* events.
|
||||
*/
|
||||
if (SDL_PrivateJoystickShouldIgnoreEvent()) {
|
||||
if ((value > info->zero && value >= info->value) ||
|
||||
if (info->sending_initial_value ||
|
||||
(value > info->zero && value >= info->value) ||
|
||||
(value < info->zero && value <= info->value)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1757,8 +1799,13 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
|
||||
size_t prefixlen = SDL_strlen(replacements[i].prefix);
|
||||
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
|
||||
size_t replacementlen = SDL_strlen(replacements[i].replacement);
|
||||
SDL_memcpy(name, replacements[i].replacement, replacementlen);
|
||||
SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1));
|
||||
if (replacementlen <= prefixlen) {
|
||||
SDL_memcpy(name, replacements[i].replacement, replacementlen);
|
||||
SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen)+1);
|
||||
len -= (prefixlen - replacementlen);
|
||||
} else {
|
||||
/* FIXME: Need to handle the expand case by reallocating the string */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1768,11 +1815,9 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
|
||||
int matchlen = PrefixMatch(name, &name[i]);
|
||||
if (matchlen > 0 && name[matchlen-1] == ' ') {
|
||||
SDL_memmove(name, name+matchlen, len-matchlen+1);
|
||||
len -= matchlen;
|
||||
break;
|
||||
} else if (matchlen > 0 && name[matchlen] == ' ') {
|
||||
SDL_memmove(name, name+matchlen+1, len-matchlen);
|
||||
len -= (matchlen + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1961,7 +2006,7 @@ SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||
if (product_id == USB_PRODUCT_XBOX_SERIES_X ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) {
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1986,10 +2031,14 @@ SDL_bool
|
||||
SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||
if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
|
||||
if (product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLE ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) {
|
||||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
@@ -2389,8 +2438,9 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
|
||||
/* Additional entries */
|
||||
/*****************************************************************/
|
||||
|
||||
/* Anne Pro II Keyboard */
|
||||
MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard */
|
||||
MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Mouse */
|
||||
MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
@@ -2713,6 +2763,13 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We ignore events if we don't have keyboard focus, except for touch release */
|
||||
if (SDL_PrivateJoystickShouldIgnoreEvent()) {
|
||||
if (event_type != SDL_CONTROLLERTOUCHPADUP) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update internal joystick state */
|
||||
finger_info->state = state;
|
||||
finger_info->x = x;
|
||||
@@ -2742,6 +2799,11 @@ int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, const
|
||||
int i;
|
||||
int posted = 0;
|
||||
|
||||
/* We ignore events if we don't have keyboard focus */
|
||||
if (SDL_PrivateJoystickShouldIgnoreEvent()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < joystick->nsensors; ++i) {
|
||||
SDL_JoystickSensorInfo *sensor = &joystick->sensors[i];
|
||||
|
||||
|
10
externals/SDL/src/joystick/SDL_sysjoystick.h
vendored
10
externals/SDL/src/joystick/SDL_sysjoystick.h
vendored
@@ -36,6 +36,7 @@ typedef struct _SDL_JoystickAxisInfo
|
||||
SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */
|
||||
SDL_bool has_second_value; /* Whether we've seen a second value on the axis yet */
|
||||
SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */
|
||||
SDL_bool sending_initial_value; /* Whether we are sending the initial axis value */
|
||||
} SDL_JoystickAxisInfo;
|
||||
|
||||
typedef struct _SDL_JoystickTouchpadFingerInfo
|
||||
@@ -120,6 +121,11 @@ struct _SDL_Joystick
|
||||
#define SDL_HARDWARE_BUS_USB 0x03
|
||||
#define SDL_HARDWARE_BUS_BLUETOOTH 0x05
|
||||
|
||||
/* Joystick capability flags for GetCapabilities() */
|
||||
#define SDL_JOYCAP_LED 0x01
|
||||
#define SDL_JOYCAP_RUMBLE 0x02
|
||||
#define SDL_JOYCAP_RUMBLE_TRIGGERS 0x04
|
||||
|
||||
/* Macro to combine a USB vendor ID and product ID into a single Uint32 value */
|
||||
#define MAKE_VIDPID(VID, PID) (((Uint32)(VID))<<16|(PID))
|
||||
|
||||
@@ -163,8 +169,10 @@ typedef struct _SDL_JoystickDriver
|
||||
int (*Rumble)(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
int (*RumbleTriggers)(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
|
||||
|
||||
/* Capability detection */
|
||||
Uint32 (*GetCapabilities)(SDL_Joystick *joystick);
|
||||
|
||||
/* LED functionality */
|
||||
SDL_bool (*HasLED)(SDL_Joystick *joystick);
|
||||
int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
|
||||
|
||||
/* General effects */
|
||||
|
@@ -616,10 +616,10 @@ ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint1
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ANDROID_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
ANDROID_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -719,7 +719,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
|
||||
ANDROID_JoystickOpen,
|
||||
ANDROID_JoystickRumble,
|
||||
ANDROID_JoystickRumbleTriggers,
|
||||
ANDROID_JoystickHasLED,
|
||||
ANDROID_JoystickGetCapabilities,
|
||||
ANDROID_JoystickSetLED,
|
||||
ANDROID_JoystickSendEffect,
|
||||
ANDROID_JoystickSetSensorsEnabled,
|
||||
|
18
externals/SDL/src/joystick/bsd/SDL_bsdjoystick.c
vendored
18
externals/SDL/src/joystick/bsd/SDL_bsdjoystick.c
vendored
@@ -240,7 +240,7 @@ BSD_JoystickInit(void)
|
||||
}
|
||||
for (i = 0; i < MAX_JOY_JOYS; i++) {
|
||||
SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
|
||||
fd = open(s, O_RDONLY);
|
||||
fd = open(s, O_RDONLY | O_CLOEXEC);
|
||||
if (fd != -1) {
|
||||
joynames[numjoysticks++] = SDL_strdup(s);
|
||||
close(fd);
|
||||
@@ -357,7 +357,7 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index)
|
||||
int fd;
|
||||
int i;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
return SDL_SetError("%s: %s", path, strerror(errno));
|
||||
}
|
||||
@@ -426,7 +426,7 @@ BSD_JoystickOpen(SDL_Joystick *joy, int device_index)
|
||||
str[i] = UGETW(usd.usd_desc.bString[i]);
|
||||
}
|
||||
str[i] = '\0';
|
||||
asprintf(&new_name, "%s @ %s", str, path);
|
||||
SDL_asprintf(&new_name, "%s @ %s", str, path);
|
||||
if (new_name != NULL) {
|
||||
SDL_free(joydevnames[numjoysticks]);
|
||||
joydevnames[numjoysticks] = new_name;
|
||||
@@ -552,7 +552,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
|
||||
|
||||
if (joy->hwdata->type == BSDJOY_JOY) {
|
||||
while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
|
||||
if (abs(x - gameport.x) > 8) {
|
||||
if (SDL_abs(x - gameport.x) > 8) {
|
||||
x = gameport.x;
|
||||
if (x < xmin) {
|
||||
xmin = x;
|
||||
@@ -569,7 +569,7 @@ BSD_JoystickUpdate(SDL_Joystick *joy)
|
||||
v *= 32768 / ((xmax - xmin + 1) / 2);
|
||||
SDL_PrivateJoystickAxis(joy, 0, v);
|
||||
}
|
||||
if (abs(y - gameport.y) > 8) {
|
||||
if (SDL_abs(y - gameport.y) > 8) {
|
||||
y = gameport.y;
|
||||
if (y < ymin) {
|
||||
ymin = y;
|
||||
@@ -777,10 +777,10 @@ BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
BSD_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
BSD_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -814,7 +814,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
|
||||
BSD_JoystickOpen,
|
||||
BSD_JoystickRumble,
|
||||
BSD_JoystickRumbleTriggers,
|
||||
BSD_JoystickHasLED,
|
||||
BSD_JoystickGetCapabilities,
|
||||
BSD_JoystickSetLED,
|
||||
BSD_JoystickSendEffect,
|
||||
BSD_JoystickSetSensorsEnabled,
|
||||
|
10
externals/SDL/src/joystick/controller_type.h
vendored
10
externals/SDL/src/joystick/controller_type.h
vendored
@@ -325,9 +325,15 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ 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 (Bluetooth)
|
||||
{ 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
|
||||
@@ -579,7 +585,7 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ 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, 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
|
||||
|
@@ -939,10 +939,21 @@ DARWIN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DARWIN_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
DARWIN_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
recDevice *device = joystick->hwdata;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!device) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (device->ffservice) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1111,7 +1122,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
|
||||
DARWIN_JoystickOpen,
|
||||
DARWIN_JoystickRumble,
|
||||
DARWIN_JoystickRumbleTriggers,
|
||||
DARWIN_JoystickHasLED,
|
||||
DARWIN_JoystickGetCapabilities,
|
||||
DARWIN_JoystickSetLED,
|
||||
DARWIN_JoystickSendEffect,
|
||||
DARWIN_JoystickSetSensorsEnabled,
|
||||
|
@@ -95,10 +95,10 @@ DUMMY_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
DUMMY_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
DUMMY_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -153,7 +153,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
|
||||
DUMMY_JoystickOpen,
|
||||
DUMMY_JoystickRumble,
|
||||
DUMMY_JoystickRumbleTriggers,
|
||||
DUMMY_JoystickHasLED,
|
||||
DUMMY_JoystickGetCapabilities,
|
||||
DUMMY_JoystickSetLED,
|
||||
DUMMY_JoystickSendEffect,
|
||||
DUMMY_JoystickSetSensorsEnabled,
|
||||
|
@@ -414,10 +414,10 @@ EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
EMSCRIPTEN_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
EMSCRIPTEN_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -451,7 +451,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
|
||||
EMSCRIPTEN_JoystickOpen,
|
||||
EMSCRIPTEN_JoystickRumble,
|
||||
EMSCRIPTEN_JoystickRumbleTriggers,
|
||||
EMSCRIPTEN_JoystickHasLED,
|
||||
EMSCRIPTEN_JoystickGetCapabilities,
|
||||
EMSCRIPTEN_JoystickSetLED,
|
||||
EMSCRIPTEN_JoystickSendEffect,
|
||||
EMSCRIPTEN_JoystickSetSensorsEnabled,
|
||||
|
@@ -271,9 +271,9 @@ extern "C"
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool HAIKU_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32 HAIKU_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HAIKU_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
@@ -305,7 +305,7 @@ extern "C"
|
||||
HAIKU_JoystickOpen,
|
||||
HAIKU_JoystickRumble,
|
||||
HAIKU_JoystickRumbleTriggers,
|
||||
HAIKU_JoystickHasLED,
|
||||
HAIKU_JoystickGetCapabilities,
|
||||
HAIKU_JoystickSetLED,
|
||||
HAIKU_JoystickSendEffect,
|
||||
HAIKU_JoystickSetSensorsEnabled,
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hidapijoystick_c.h"
|
||||
#include "SDL_hidapi_rumble.h"
|
||||
#include "../../hidapi/SDL_hidapi.h"
|
||||
#include "../../hidapi/SDL_hidapi_c.h"
|
||||
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
|
||||
@@ -129,7 +129,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -154,7 +154,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
} else {
|
||||
/* This is all that's needed to initialize the device. Really! */
|
||||
if (hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
|
||||
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
|
||||
SDL_SetError("Couldn't initialize WUP-028");
|
||||
goto error;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
SDL_Delay(10);
|
||||
|
||||
/* Add all the applicable joysticks */
|
||||
while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
#ifdef DEBUG_GAMECUBE_PROTOCOL
|
||||
HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
|
||||
#endif
|
||||
@@ -204,7 +204,7 @@ error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -389,7 +389,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
int size;
|
||||
|
||||
/* Read input packet */
|
||||
while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
#ifdef DEBUG_GAMECUBE_PROTOCOL
|
||||
//HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
|
||||
#endif
|
||||
@@ -464,10 +464,26 @@ HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverGameCube_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->pc_mode) {
|
||||
Uint8 i;
|
||||
|
||||
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
|
||||
if (joystick->instance_id == ctx->joysticks[i]) {
|
||||
if (!ctx->wireless[i] && ctx->rumbleAllowed[i]) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -510,7 +526,7 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -523,6 +539,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverGameCube_IsSupportedDevice,
|
||||
HIDAPI_DriverGameCube_GetDeviceName,
|
||||
HIDAPI_DriverGameCube_InitDevice,
|
||||
@@ -532,7 +549,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
|
||||
HIDAPI_DriverGameCube_OpenJoystick,
|
||||
HIDAPI_DriverGameCube_RumbleJoystick,
|
||||
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverGameCube_HasJoystickLED,
|
||||
HIDAPI_DriverGameCube_GetJoystickCapabilities,
|
||||
HIDAPI_DriverGameCube_SetJoystickLED,
|
||||
HIDAPI_DriverGameCube_SendJoystickEffect,
|
||||
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
|
||||
|
@@ -87,7 +87,7 @@ HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -132,10 +132,16 @@ HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverLuna_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverLuna_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -386,7 +392,7 @@ HIDAPI_DriverLuna_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_LUNA_PROTOCOL
|
||||
HIDAPI_DumpPacket("Amazon Luna packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -413,7 +419,7 @@ HIDAPI_DriverLuna_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -432,6 +438,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_LUNA,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverLuna_IsSupportedDevice,
|
||||
HIDAPI_DriverLuna_GetDeviceName,
|
||||
HIDAPI_DriverLuna_InitDevice,
|
||||
@@ -441,7 +448,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
|
||||
HIDAPI_DriverLuna_OpenJoystick,
|
||||
HIDAPI_DriverLuna_RumbleJoystick,
|
||||
HIDAPI_DriverLuna_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverLuna_HasJoystickLED,
|
||||
HIDAPI_DriverLuna_GetJoystickCapabilities,
|
||||
HIDAPI_DriverLuna_SetJoystickLED,
|
||||
HIDAPI_DriverLuna_SendJoystickEffect,
|
||||
HIDAPI_DriverLuna_SetJoystickSensorsEnabled,
|
||||
|
@@ -163,11 +163,11 @@ HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
return SDL_hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id)
|
||||
@@ -415,7 +415,7 @@ HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device)
|
||||
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
|
||||
Uint8 data[78];
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
data[0] = k_EPS4ReportIdBluetoothEffects;
|
||||
data[1] = 0xC0; /* Magic value HID + CRC */
|
||||
@@ -479,7 +479,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->joystick = joystick;
|
||||
ctx->last_packet = SDL_GetTicks();
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -511,7 +511,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->is_bluetooth = SDL_TRUE;
|
||||
|
||||
/* Read a report to see if we're in enhanced mode */
|
||||
size = hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
if (size > 0) {
|
||||
HIDAPI_DumpPacket("PS4 first packet: size = %d", data, size);
|
||||
@@ -598,10 +598,17 @@ HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverPS4_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode && ctx->effects_supported) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -632,7 +639,7 @@ HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
HIDAPI_DriverPS4_SetEnhancedMode(device, joystick);
|
||||
}
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
if (ctx->is_bluetooth) {
|
||||
data[0] = k_EPS4ReportIdBluetoothEffects;
|
||||
@@ -684,7 +691,7 @@ HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
|
||||
HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */
|
||||
@@ -846,7 +853,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS4 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -908,7 +915,7 @@ HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -926,6 +933,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_PS4,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverPS4_IsSupportedDevice,
|
||||
HIDAPI_DriverPS4_GetDeviceName,
|
||||
HIDAPI_DriverPS4_InitDevice,
|
||||
@@ -935,7 +943,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
|
||||
HIDAPI_DriverPS4_OpenJoystick,
|
||||
HIDAPI_DriverPS4_RumbleJoystick,
|
||||
HIDAPI_DriverPS4_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS4_HasJoystickLED,
|
||||
HIDAPI_DriverPS4_GetJoystickCapabilities,
|
||||
HIDAPI_DriverPS4_SetJoystickLED,
|
||||
HIDAPI_DriverPS4_SendJoystickEffect,
|
||||
HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
|
||||
|
@@ -192,11 +192,11 @@ HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
return SDL_hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -471,7 +471,7 @@ HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device)
|
||||
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
|
||||
Uint8 data[78];
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
data[0] = k_EPS5ReportIdBluetoothEffects;
|
||||
data[1] = 0x02; /* Magic value */
|
||||
@@ -553,7 +553,7 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->joystick = joystick;
|
||||
ctx->last_packet = SDL_GetTicks();
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -562,7 +562,7 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
device->context = ctx;
|
||||
|
||||
/* Read a report to see what mode we're in */
|
||||
size = hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
#ifdef DEBUG_PS5_PROTOCOL
|
||||
if (size > 0) {
|
||||
HIDAPI_DumpPacket("PS5 first packet: size = %d", data, size);
|
||||
@@ -663,10 +663,17 @@ HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverPS5_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -696,7 +703,7 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
|
||||
}
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
if (ctx->is_bluetooth) {
|
||||
data[0] = k_EPS5ReportIdBluetoothEffects;
|
||||
@@ -761,7 +768,7 @@ HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
|
||||
HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
|
||||
{
|
||||
Sint16 axis;
|
||||
|
||||
@@ -855,7 +862,7 @@ HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet)
|
||||
HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
|
||||
@@ -1010,7 +1017,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_PS5_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS5 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -1071,7 +1078,7 @@ HIDAPI_DriverPS5_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1089,6 +1096,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_PS5,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverPS5_IsSupportedDevice,
|
||||
HIDAPI_DriverPS5_GetDeviceName,
|
||||
HIDAPI_DriverPS5_InitDevice,
|
||||
@@ -1098,7 +1106,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
|
||||
HIDAPI_DriverPS5_OpenJoystick,
|
||||
HIDAPI_DriverPS5_RumbleJoystick,
|
||||
HIDAPI_DriverPS5_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS5_HasJoystickLED,
|
||||
HIDAPI_DriverPS5_GetJoystickCapabilities,
|
||||
HIDAPI_DriverPS5_SetJoystickLED,
|
||||
HIDAPI_DriverPS5_SendJoystickEffect,
|
||||
HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
|
||||
|
@@ -80,7 +80,7 @@ static int SDL_HIDAPI_RumbleThread(void *data)
|
||||
#ifdef DEBUG_RUMBLE
|
||||
HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size);
|
||||
#endif
|
||||
hid_write(request->device->dev, request->data, request->size);
|
||||
SDL_hid_write(request->device->dev, request->data, request->size);
|
||||
}
|
||||
SDL_UnlockMutex(request->device->dev_lock);
|
||||
(void)SDL_AtomicDecRef(&request->device->rumble_pending);
|
||||
|
@@ -88,7 +88,7 @@ HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -126,10 +126,10 @@ HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverStadia_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -267,7 +267,7 @@ HIDAPI_DriverStadia_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_STADIA_PROTOCOL
|
||||
HIDAPI_DumpPacket("Google Stadia packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -287,7 +287,7 @@ HIDAPI_DriverStadia_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_STADIA,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverStadia_IsSupportedDevice,
|
||||
HIDAPI_DriverStadia_GetDeviceName,
|
||||
HIDAPI_DriverStadia_InitDevice,
|
||||
@@ -315,7 +316,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
|
||||
HIDAPI_DriverStadia_OpenJoystick,
|
||||
HIDAPI_DriverStadia_RumbleJoystick,
|
||||
HIDAPI_DriverStadia_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverStadia_HasJoystickLED,
|
||||
HIDAPI_DriverStadia_GetJoystickCapabilities,
|
||||
HIDAPI_DriverStadia_SetJoystickLED,
|
||||
HIDAPI_DriverStadia_SendJoystickEffect,
|
||||
HIDAPI_DriverStadia_SetJoystickSensorsEnabled,
|
||||
|
219
externals/SDL/src/joystick/hidapi/SDL_hidapi_steam.c
vendored
219
externals/SDL/src/joystick/hidapi/SDL_hidapi_steam.c
vendored
@@ -190,7 +190,7 @@ typedef struct
|
||||
|
||||
|
||||
// Wireless firmware quirk: the firmware intentionally signals "failure" when performing
|
||||
// SET_FEATURE / GET_FEATURE when it actually means "pending radio round-trip". The only
|
||||
// SET_FEATURE / GET_FEATURE when it actually means "pending radio roundtrip". The only
|
||||
// way to make SET_FEATURE / GET_FEATURE work is to loop several times with a sleep. If
|
||||
// it takes more than 50ms to get the response for SET_FEATURE / GET_FEATURE, we assume
|
||||
// that the controller has failed.
|
||||
@@ -220,7 +220,7 @@ static void hexdump( const uint8_t *ptr, int len )
|
||||
|
||||
static void ResetSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler )
|
||||
{
|
||||
memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) );
|
||||
SDL_memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) );
|
||||
pAssembler->nExpectedSegmentNumber = 0;
|
||||
}
|
||||
|
||||
@@ -239,6 +239,9 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
{
|
||||
if ( pAssembler->bIsBle )
|
||||
{
|
||||
uint8_t uSegmentHeader = pSegment[ 1 ];
|
||||
int nSegmentNumber = uSegmentHeader & 0x07;
|
||||
|
||||
HEXDUMP( pSegment, nSegmentLength );
|
||||
|
||||
if ( pSegment[ 0 ] != BLE_REPORT_NUMBER )
|
||||
@@ -255,7 +258,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t uSegmentHeader = pSegment[ 1 ];
|
||||
DPRINTF("GOT PACKET HEADER = 0x%x\n", uSegmentHeader);
|
||||
|
||||
if ( ( uSegmentHeader & REPORT_SEGMENT_DATA_FLAG ) == 0 )
|
||||
@@ -264,7 +266,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nSegmentNumber = uSegmentHeader & 0x07;
|
||||
if ( nSegmentNumber != pAssembler->nExpectedSegmentNumber )
|
||||
{
|
||||
ResetSteamControllerPacketAssembler( pAssembler );
|
||||
@@ -278,7 +279,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
}
|
||||
}
|
||||
|
||||
memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE,
|
||||
SDL_memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE,
|
||||
pSegment + 2, // ignore header and report number
|
||||
MAX_REPORT_SEGMENT_PAYLOAD_SIZE );
|
||||
|
||||
@@ -293,7 +294,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
else
|
||||
{
|
||||
// Just pass through
|
||||
memcpy( pAssembler->uBuffer,
|
||||
SDL_memcpy( pAssembler->uBuffer,
|
||||
pSegment,
|
||||
nSegmentLength );
|
||||
return nSegmentLength;
|
||||
@@ -304,22 +305,23 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
|
||||
#define BLE_MAX_READ_RETRIES 8
|
||||
|
||||
static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nActualDataLen )
|
||||
static int SetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65], int nActualDataLen )
|
||||
{
|
||||
DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen);
|
||||
int nRet = -1;
|
||||
bool bBle = true; // only wireless/BLE for now, though macOS could do wired in the future
|
||||
|
||||
DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen);
|
||||
|
||||
if ( bBle )
|
||||
{
|
||||
int nSegmentNumber = 0;
|
||||
uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
unsigned char *pBufferPtr = uBuffer + 1;
|
||||
|
||||
if ( nActualDataLen < 1 )
|
||||
return -1;
|
||||
|
||||
int nSegmentNumber = 0;
|
||||
uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
|
||||
// Skip report number in data
|
||||
unsigned char *pBufferPtr = uBuffer + 1;
|
||||
nActualDataLen--;
|
||||
|
||||
while ( nActualDataLen > 0 )
|
||||
@@ -329,15 +331,15 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc
|
||||
nActualDataLen -= nBytesInPacket;
|
||||
|
||||
// Construct packet
|
||||
memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) );
|
||||
SDL_memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) );
|
||||
uPacketBuffer[ 0 ] = BLE_REPORT_NUMBER;
|
||||
uPacketBuffer[ 1 ] = GetSegmentHeader( nSegmentNumber, nActualDataLen == 0 );
|
||||
memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket );
|
||||
SDL_memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket );
|
||||
|
||||
pBufferPtr += nBytesInPacket;
|
||||
nSegmentNumber++;
|
||||
|
||||
nRet = hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) );
|
||||
nRet = SDL_hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) );
|
||||
DPRINTF("SetFeatureReport() ret = %d\n", nRet);
|
||||
}
|
||||
}
|
||||
@@ -345,24 +347,26 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc
|
||||
return nRet;
|
||||
}
|
||||
|
||||
static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
static int GetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65] )
|
||||
{
|
||||
DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer );
|
||||
int nRet = -1;
|
||||
bool bBle = true;
|
||||
|
||||
DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer );
|
||||
|
||||
if ( bBle )
|
||||
{
|
||||
int nRetries = 0;
|
||||
uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
|
||||
SteamControllerPacketAssembler assembler;
|
||||
InitializeSteamControllerPacketAssembler( &assembler );
|
||||
|
||||
int nRetries = 0;
|
||||
uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
while( nRetries < BLE_MAX_READ_RETRIES )
|
||||
{
|
||||
memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) );
|
||||
SDL_memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) );
|
||||
uSegmentBuffer[ 0 ] = BLE_REPORT_NUMBER;
|
||||
nRet = hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) );
|
||||
nRet = SDL_hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) );
|
||||
DPRINTF( "GetFeatureReport ble ret=%d\n", nRet );
|
||||
HEXDUMP( uSegmentBuffer, nRet );
|
||||
|
||||
@@ -382,7 +386,7 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
{
|
||||
// Leave space for "report number"
|
||||
uBuffer[ 0 ] = 0;
|
||||
memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength );
|
||||
SDL_memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength );
|
||||
return nPacketLength;
|
||||
}
|
||||
}
|
||||
@@ -396,11 +400,12 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
return nRet;
|
||||
}
|
||||
|
||||
static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse )
|
||||
static int ReadResponse( SDL_hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse )
|
||||
{
|
||||
DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse );
|
||||
int nRet = GetFeatureReport( dev, uBuffer );
|
||||
|
||||
DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse );
|
||||
|
||||
if ( nRet < 0 )
|
||||
return nRet;
|
||||
|
||||
@@ -416,13 +421,18 @@ static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResp
|
||||
//---------------------------------------------------------------------------
|
||||
// Reset steam controller (unmap buttons and pads) and re-fetch capability bits
|
||||
//---------------------------------------------------------------------------
|
||||
static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
static bool ResetSteamController( SDL_hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS )
|
||||
{
|
||||
DPRINTF( "ResetSteamController hid=%p\n", dev );
|
||||
// Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer.
|
||||
unsigned char buf[65];
|
||||
int res = -1;
|
||||
int res = -1, i;
|
||||
int nSettings = 0;
|
||||
int nAttributesLength;
|
||||
FeatureReportMsg *msg;
|
||||
uint32_t unUpdateRateUS = 9000; // Good default rate
|
||||
|
||||
DPRINTF( "ResetSteamController hid=%p\n", dev );
|
||||
|
||||
buf[0] = 0;
|
||||
buf[1] = ID_GET_ATTRIBUTES_VALUES;
|
||||
res = SetFeatureReport( dev, buf, 2 );
|
||||
@@ -444,14 +454,40 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
return false;
|
||||
}
|
||||
|
||||
int nAttributesLength = buf[ 2 ];
|
||||
nAttributesLength = buf[ 2 ];
|
||||
if ( nAttributesLength > res )
|
||||
{
|
||||
if ( !bSuppressErrorSpew )
|
||||
printf( "Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
msg = (FeatureReportMsg *)&buf[1];
|
||||
for ( i = 0; i < (int)msg->header.length / sizeof( ControllerAttribute ); ++i )
|
||||
{
|
||||
uint8_t unAttribute = msg->payload.getAttributes.attributes[i].attributeTag;
|
||||
uint32_t unValue = msg->payload.getAttributes.attributes[i].attributeValue;
|
||||
|
||||
switch ( unAttribute )
|
||||
{
|
||||
case ATTRIB_UNIQUE_ID:
|
||||
break;
|
||||
case ATTRIB_PRODUCT_ID:
|
||||
break;
|
||||
case ATTRIB_CAPABILITIES:
|
||||
break;
|
||||
case ATTRIB_CONNECTION_INTERVAL_IN_US:
|
||||
unUpdateRateUS = unValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( punUpdateRateUS )
|
||||
{
|
||||
*punUpdateRateUS = unUpdateRateUS;
|
||||
}
|
||||
|
||||
// Clear digital button mappings
|
||||
buf[0] = 0;
|
||||
buf[1] = ID_CLEAR_DIGITAL_MAPPINGS;
|
||||
@@ -464,7 +500,7 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
}
|
||||
|
||||
// Reset the default settings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_LOAD_DEFAULT_SETTINGS;
|
||||
buf[2] = 0;
|
||||
res = SetFeatureReport( dev, buf, 3 );
|
||||
@@ -476,14 +512,13 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
}
|
||||
|
||||
// Apply custom settings - clear trackpad modes (cancel mouse emulation), etc
|
||||
int nSettings = 0;
|
||||
#define ADD_SETTING(SETTING, VALUE) \
|
||||
buf[3+nSettings*3] = SETTING; \
|
||||
buf[3+nSettings*3+1] = ((uint16_t)VALUE)&0xFF; \
|
||||
buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
++nSettings;
|
||||
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
ADD_SETTING( SETTING_WIRELESS_PACKET_VERSION, 2 );
|
||||
ADD_SETTING( SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE );
|
||||
@@ -512,7 +547,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
int iRetry;
|
||||
for ( iRetry = 0; iRetry < 2; ++iRetry )
|
||||
{
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_GET_DIGITAL_MAPPINGS;
|
||||
buf[2] = 1; // one byte - requesting from index 0
|
||||
buf[3] = 0;
|
||||
@@ -545,7 +580,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
}
|
||||
|
||||
// Set our new mappings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_DIGITAL_MAPPINGS;
|
||||
buf[2] = 6; // 2 settings x 3 bytes
|
||||
buf[3] = IO_DIGITAL_BUTTON_RIGHT_TRIGGER;
|
||||
@@ -571,36 +606,36 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
//---------------------------------------------------------------------------
|
||||
// Read from a Steam Controller
|
||||
//---------------------------------------------------------------------------
|
||||
static int ReadSteamController( hid_device *dev, uint8_t *pData, int nDataSize )
|
||||
static int ReadSteamController( SDL_hid_device *dev, uint8_t *pData, int nDataSize )
|
||||
{
|
||||
memset( pData, 0, nDataSize );
|
||||
SDL_memset( pData, 0, nDataSize );
|
||||
pData[ 0 ] = BLE_REPORT_NUMBER; // hid_read will also overwrite this with the same value, 0x03
|
||||
return hid_read( dev, pData, nDataSize );
|
||||
return SDL_hid_read( dev, pData, nDataSize );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Close a Steam Controller
|
||||
//---------------------------------------------------------------------------
|
||||
static void CloseSteamController( hid_device *dev )
|
||||
static void CloseSteamController( SDL_hid_device *dev )
|
||||
{
|
||||
// Switch the Steam Controller back to lizard mode so it works with the OS
|
||||
unsigned char buf[65];
|
||||
int nSettings = 0;
|
||||
|
||||
// Reset digital button mappings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_DEFAULT_DIGITAL_MAPPINGS;
|
||||
SetFeatureReport( dev, buf, 2 );
|
||||
|
||||
// Reset the default settings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_LOAD_DEFAULT_SETTINGS;
|
||||
buf[2] = 0;
|
||||
SetFeatureReport( dev, buf, 3 );
|
||||
|
||||
// Reset mouse mode for lizard mode
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
ADD_SETTING( SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_ABSOLUTE_MOUSE );
|
||||
buf[2] = nSettings*3;
|
||||
@@ -651,14 +686,23 @@ static void RotatePadShort( short *pX, short *pY, float flAngleInRad )
|
||||
//---------------------------------------------------------------------------
|
||||
static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState, ValveControllerStatePacket_t *pStatePacket )
|
||||
{
|
||||
memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel));
|
||||
int nLeftPadX;
|
||||
int nLeftPadY;
|
||||
int nRightPadX;
|
||||
int nRightPadY;
|
||||
int nPadOffset;
|
||||
|
||||
// 15 degrees in rad
|
||||
const float flRotationAngle = 0.261799f;
|
||||
|
||||
SDL_memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel));
|
||||
|
||||
//pState->eControllerType = m_eControllerType;
|
||||
pState->eControllerType = 2; // k_eControllerType_SteamController;
|
||||
pState->unPacketNum = pStatePacket->unPacketNum;
|
||||
|
||||
// We have a chunk of trigger data in the packet format here, so zero it out afterwards
|
||||
memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8);
|
||||
SDL_memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8);
|
||||
pState->ulButtons &= ~0xFFFF000000LL;
|
||||
|
||||
// The firmware uses this bit to tell us what kind of data is packed into the left two axises
|
||||
@@ -735,18 +779,14 @@ static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState,
|
||||
pState->sRightPadX = pStatePacket->sRightPadX;
|
||||
pState->sRightPadY = pStatePacket->sRightPadY;
|
||||
|
||||
int nLeftPadX = pState->sLeftPadX;
|
||||
int nLeftPadY = pState->sLeftPadY;
|
||||
int nRightPadX = pState->sRightPadX;
|
||||
int nRightPadY = pState->sRightPadY;
|
||||
|
||||
// 15 degrees in rad
|
||||
const float flRotationAngle = 0.261799f;
|
||||
nLeftPadX = pState->sLeftPadX;
|
||||
nLeftPadY = pState->sLeftPadY;
|
||||
nRightPadX = pState->sRightPadX;
|
||||
nRightPadY = pState->sRightPadY;
|
||||
|
||||
RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle);
|
||||
RotatePad(&nRightPadX, &nRightPadY, flRotationAngle);
|
||||
|
||||
int nPadOffset;
|
||||
if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK)
|
||||
nPadOffset = 1000;
|
||||
else
|
||||
@@ -782,7 +822,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
ucOptionDataMask |= (uint32_t)(*pData++) << 8;
|
||||
if ( ucOptionDataMask & k_EBLEButtonChunk1 )
|
||||
{
|
||||
memcpy( &pState->ulButtons, pData, 3 );
|
||||
SDL_memcpy( &pState->ulButtons, pData, 3 );
|
||||
pData += 3;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEButtonChunk2 )
|
||||
@@ -804,14 +844,14 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
// This doesn't handle any of the special headcrab stuff for raw joystick which is OK for now since that FW doesn't support
|
||||
// this protocol yet either
|
||||
int nLength = sizeof( pState->sLeftStickX ) + sizeof( pState->sLeftStickY );
|
||||
memcpy( &pState->sLeftStickX, pData, nLength );
|
||||
SDL_memcpy( &pState->sLeftStickX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLELeftTrackpadChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sLeftPadX ) + sizeof( pState->sLeftPadY );
|
||||
int nPadOffset;
|
||||
memcpy( &pState->sLeftPadX, pData, nLength );
|
||||
SDL_memcpy( &pState->sLeftPadX, pData, nLength );
|
||||
if ( pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK )
|
||||
nPadOffset = 1000;
|
||||
else
|
||||
@@ -827,7 +867,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
int nLength = sizeof( pState->sRightPadX ) + sizeof( pState->sRightPadY );
|
||||
int nPadOffset = 0;
|
||||
|
||||
memcpy( &pState->sRightPadX, pData, nLength );
|
||||
SDL_memcpy( &pState->sRightPadX, pData, nLength );
|
||||
|
||||
if ( pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK )
|
||||
nPadOffset = 1000;
|
||||
@@ -842,19 +882,19 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
if ( ucOptionDataMask & k_EBLEIMUAccelChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ );
|
||||
memcpy( &pState->sAccelX, pData, nLength );
|
||||
SDL_memcpy( &pState->sAccelX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEIMUGyroChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ );
|
||||
memcpy( &pState->sGyroX, pData, nLength );
|
||||
SDL_memcpy( &pState->sGyroX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEIMUQuatChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sGyroQuatW ) + sizeof( pState->sGyroQuatX ) + sizeof( pState->sGyroQuatY ) + sizeof( pState->sGyroQuatZ );
|
||||
memcpy( &pState->sGyroQuatW, pData, nLength );
|
||||
SDL_memcpy( &pState->sGyroQuatW, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
return true;
|
||||
@@ -950,6 +990,7 @@ static bool UpdateSteamControllerState( const uint8_t *pData, int nDataSize, Ste
|
||||
/*****************************************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
SDL_bool report_sensors;
|
||||
SteamControllerPacketAssembler m_assembler;
|
||||
SteamControllerStateInternal_t m_state;
|
||||
SteamControllerStateInternal_t m_last_state;
|
||||
@@ -989,6 +1030,8 @@ static SDL_bool
|
||||
HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_DriverSteam_Context *ctx;
|
||||
uint32_t update_rate_in_us = 0;
|
||||
float update_rate_in_hz = 0.0f;
|
||||
|
||||
ctx = (SDL_DriverSteam_Context *)SDL_calloc(1, sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
@@ -997,15 +1040,20 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
}
|
||||
device->context = ctx;
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
goto error;
|
||||
}
|
||||
SDL_hid_set_nonblocking(device->dev, 1);
|
||||
|
||||
if (!ResetSteamController(device->dev, false)) {
|
||||
if (!ResetSteamController(device->dev, false, &update_rate_in_us)) {
|
||||
SDL_SetError("Couldn't reset controller");
|
||||
goto error;
|
||||
}
|
||||
if (update_rate_in_us > 0) {
|
||||
update_rate_in_hz = 1000000.0f / update_rate_in_us;
|
||||
}
|
||||
|
||||
InitializeSteamControllerPacketAssembler(&ctx->m_assembler);
|
||||
|
||||
@@ -1013,13 +1061,16 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
joystick->nbuttons = 17;
|
||||
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
|
||||
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz);
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz);
|
||||
|
||||
return SDL_TRUE;
|
||||
|
||||
error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -1044,11 +1095,11 @@ HIDAPI_DriverSteam_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystic
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverSteam_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverSteam_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* You should use the full Steam Input API for LED support */
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1067,8 +1118,25 @@ HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *j
|
||||
static int
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
/* You should use the full Steam Input API for sensor support */
|
||||
return SDL_Unsupported();
|
||||
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
|
||||
unsigned char buf[65];
|
||||
int nSettings = 0;
|
||||
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
if (enabled) {
|
||||
ADD_SETTING( SETTING_GYRO_MODE, 0x18 /* SETTING_GYRO_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO */ );
|
||||
} else {
|
||||
ADD_SETTING( SETTING_GYRO_MODE, 0x00 /* SETTING_GYRO_MODE_OFF */ );
|
||||
}
|
||||
buf[2] = nSettings*3;
|
||||
if (SetFeatureReport( device->dev, buf, 3+nSettings*3 ) < 0) {
|
||||
return SDL_SetError("Couldn't write feature report");
|
||||
}
|
||||
|
||||
ctx->report_sensors = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
@@ -1165,6 +1233,20 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, ctx->m_state.sRightPadX);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~ctx->m_state.sRightPadY);
|
||||
|
||||
if (ctx->report_sensors) {
|
||||
float values[3];
|
||||
|
||||
values[0] = (ctx->m_state.sGyroX / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
values[1] = (ctx->m_state.sGyroZ / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
values[2] = (ctx->m_state.sGyroY / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, values, 3);
|
||||
|
||||
values[0] = (ctx->m_state.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
values[1] = (ctx->m_state.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
values[2] = (-ctx->m_state.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, values, 3);
|
||||
}
|
||||
|
||||
ctx->m_last_state = ctx->m_state;
|
||||
}
|
||||
|
||||
@@ -1184,7 +1266,7 @@ HIDAPI_DriverSteam_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
{
|
||||
CloseSteamController(device->dev);
|
||||
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1202,6 +1284,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_STEAM,
|
||||
SDL_TRUE,
|
||||
SDL_FALSE,
|
||||
HIDAPI_DriverSteam_IsSupportedDevice,
|
||||
HIDAPI_DriverSteam_GetDeviceName,
|
||||
HIDAPI_DriverSteam_InitDevice,
|
||||
@@ -1211,7 +1294,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
|
||||
HIDAPI_DriverSteam_OpenJoystick,
|
||||
HIDAPI_DriverSteam_RumbleJoystick,
|
||||
HIDAPI_DriverSteam_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSteam_HasJoystickLED,
|
||||
HIDAPI_DriverSteam_GetJoystickCapabilities,
|
||||
HIDAPI_DriverSteam_SetJoystickLED,
|
||||
HIDAPI_DriverSteam_SendJoystickEffect,
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled,
|
||||
|
@@ -346,13 +346,13 @@ static int ReadInput(SDL_DriverSwitch_Context *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0);
|
||||
return SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0);
|
||||
}
|
||||
|
||||
static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int size)
|
||||
{
|
||||
#ifdef SWITCH_SYNCHRONOUS_WRITES
|
||||
return hid_write(ctx->device->dev, data, size);
|
||||
return SDL_hid_write(ctx->device->dev, data, size);
|
||||
#else
|
||||
/* Use the rumble thread for general asynchronous writes */
|
||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
||||
@@ -418,7 +418,7 @@ static void ConstructSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommand
|
||||
outPacket->commonData.ucPacketType = k_eSwitchOutputReportIDs_RumbleAndSubcommand;
|
||||
outPacket->commonData.ucPacketNumber = ctx->m_nCommandNumber;
|
||||
|
||||
SDL_memcpy(&outPacket->commonData.rumbleData, &ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData));
|
||||
SDL_memcpy(outPacket->commonData.rumbleData, ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData));
|
||||
|
||||
outPacket->ucSubcommandID = ucCommandID;
|
||||
SDL_memcpy(outPacket->rgucSubcommandData, pBuf, ucLen);
|
||||
@@ -621,7 +621,7 @@ static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx)
|
||||
ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType;
|
||||
|
||||
// Bytes 4-9: MAC address (big-endian)
|
||||
memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
|
||||
SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
@@ -856,7 +856,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
ctx->device = device;
|
||||
device->context = ctx;
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
goto error;
|
||||
@@ -936,10 +936,13 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
|
||||
/* Set the LED state */
|
||||
if (ctx->m_bHasHomeLED) {
|
||||
if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, SDL_TRUE)) {
|
||||
SetHomeLED(ctx, 100);
|
||||
} else {
|
||||
SetHomeLED(ctx, 0);
|
||||
const char *hint = SDL_GetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED);
|
||||
if (hint && *hint) {
|
||||
if (SDL_GetStringBoolean(hint, SDL_TRUE)) {
|
||||
SetHomeLED(ctx, 100);
|
||||
} else {
|
||||
SetHomeLED(ctx, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetSlotLED(ctx, (joystick->instance_id % 4));
|
||||
@@ -983,7 +986,7 @@ error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -1103,11 +1106,18 @@ HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverSwitch_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverSwitch_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->m_bInputOnly) {
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1527,7 +1537,7 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1545,6 +1555,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_SWITCH,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverSwitch_IsSupportedDevice,
|
||||
HIDAPI_DriverSwitch_GetDeviceName,
|
||||
HIDAPI_DriverSwitch_InitDevice,
|
||||
@@ -1554,7 +1565,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
|
||||
HIDAPI_DriverSwitch_OpenJoystick,
|
||||
HIDAPI_DriverSwitch_RumbleJoystick,
|
||||
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSwitch_HasJoystickLED,
|
||||
HIDAPI_DriverSwitch_GetJoystickCapabilities,
|
||||
HIDAPI_DriverSwitch_SetJoystickLED,
|
||||
HIDAPI_DriverSwitch_SendJoystickEffect,
|
||||
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
|
||||
|
@@ -88,14 +88,14 @@ HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot)
|
||||
static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot)
|
||||
{
|
||||
const SDL_bool blink = SDL_FALSE;
|
||||
Uint8 mode = (blink ? 0x02 : 0x06) + slot;
|
||||
Uint8 led_packet[] = { 0x01, 0x03, 0x00 };
|
||||
|
||||
led_packet[2] = mode;
|
||||
if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
@@ -136,7 +136,7 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -203,11 +203,11 @@ HIDAPI_DriverXbox360_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXbox360_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXbox360_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -296,7 +296,7 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox 360 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -318,7 +318,7 @@ HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXbox360_IsSupportedDevice,
|
||||
HIDAPI_DriverXbox360_GetDeviceName,
|
||||
HIDAPI_DriverXbox360_InitDevice,
|
||||
@@ -346,7 +347,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
|
||||
HIDAPI_DriverXbox360_OpenJoystick,
|
||||
HIDAPI_DriverXbox360_RumbleJoystick,
|
||||
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXbox360_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360_SendJoystickEffect,
|
||||
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled,
|
||||
|
@@ -62,14 +62,14 @@ HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return "Xbox 360 Wireless Controller";
|
||||
}
|
||||
|
||||
static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot)
|
||||
static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot)
|
||||
{
|
||||
const SDL_bool blink = SDL_FALSE;
|
||||
Uint8 mode = (blink ? 0x02 : 0x06) + slot;
|
||||
Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
led_packet[3] = 0x40 + (mode % 0x0e);
|
||||
if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
@@ -105,7 +105,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -113,7 +113,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
device->context = ctx;
|
||||
|
||||
if (hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) {
|
||||
if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) {
|
||||
SDL_SetError("Couldn't write init packet");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@@ -173,11 +173,11 @@ HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXbox360W_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -199,7 +199,7 @@ HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_J
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size)
|
||||
HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
Sint16 axis;
|
||||
const SDL_bool invert_y_axes = SDL_TRUE;
|
||||
@@ -259,7 +259,7 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -321,7 +321,7 @@ HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -334,6 +334,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXbox360W_IsSupportedDevice,
|
||||
HIDAPI_DriverXbox360W_GetDeviceName,
|
||||
HIDAPI_DriverXbox360W_InitDevice,
|
||||
@@ -343,7 +344,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
|
||||
HIDAPI_DriverXbox360W_OpenJoystick,
|
||||
HIDAPI_DriverXbox360W_RumbleJoystick,
|
||||
HIDAPI_DriverXbox360W_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360W_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360W_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXbox360W_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360W_SendJoystickEffect,
|
||||
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
|
||||
|
@@ -44,33 +44,23 @@
|
||||
#define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50
|
||||
|
||||
|
||||
/* Connect controller */
|
||||
/* Start controller */
|
||||
static const Uint8 xboxone_init0[] = {
|
||||
0x04, 0x20, 0x00, 0x00
|
||||
};
|
||||
/* Start controller - extended? */
|
||||
static const Uint8 xboxone_init1[] = {
|
||||
0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
/* Start controller with input */
|
||||
static const Uint8 xboxone_init2[] = {
|
||||
0x05, 0x20, 0x03, 0x01, 0x00
|
||||
};
|
||||
/* Enable LED */
|
||||
static const Uint8 xboxone_init3[] = {
|
||||
static const Uint8 xboxone_init1[] = {
|
||||
0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
|
||||
};
|
||||
/* Start input reports? */
|
||||
static const Uint8 xboxone_init4[] = {
|
||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||
};
|
||||
/* Start rumble? */
|
||||
static const Uint8 xboxone_init5[] = {
|
||||
/* Setup rumble (not needed for Microsoft controllers, but it doesn't hurt) */
|
||||
static const Uint8 xboxone_init2[] = {
|
||||
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xEB
|
||||
};
|
||||
/* This controller passed security check */
|
||||
static const Uint8 security_passed_packet[] = {
|
||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* This specifies the selection of init packets that a gamepad
|
||||
@@ -90,16 +80,11 @@ typedef struct {
|
||||
|
||||
|
||||
static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xb0 } },
|
||||
/* The PDP Rock Candy controller doesn't start sending input until it gets this packet */
|
||||
{ 0x0e6f, 0x0246, 0x0000, 0x0000, security_passed_packet, sizeof(security_passed_packet), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } },
|
||||
|
||||
/* These next packets are required for third party controllers (PowerA, PDP, HORI),
|
||||
but aren't the correct protocol for Microsoft Xbox controllers.
|
||||
*/
|
||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } },
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -120,6 +105,7 @@ typedef struct {
|
||||
Uint32 send_time;
|
||||
Uint8 last_state[USB_PACKET_LENGTH];
|
||||
SDL_bool has_guide_packet;
|
||||
SDL_bool has_color_led;
|
||||
SDL_bool has_paddles;
|
||||
SDL_bool has_trigger_rumble;
|
||||
SDL_bool has_share_button;
|
||||
@@ -129,6 +115,12 @@ typedef struct {
|
||||
Uint8 right_trigger_rumble;
|
||||
} SDL_DriverXboxOne_Context;
|
||||
|
||||
static SDL_bool
|
||||
ControllerHasColorLED(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
@@ -138,7 +130,7 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
|
||||
static SDL_bool
|
||||
ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
// All the Microsoft Xbox One controllers have trigger rumble
|
||||
/* All the Microsoft Xbox One controllers have trigger rumble */
|
||||
return (vendor_id == USB_VENDOR_MICROSOFT);
|
||||
}
|
||||
|
||||
@@ -178,7 +170,10 @@ SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size)
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
||||
#endif
|
||||
hid_write(device->dev, ack_packet, sizeof(ack_packet));
|
||||
if (SDL_HIDAPI_LockRumble() < 0 ||
|
||||
SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) {
|
||||
SDL_SetError("Couldn't send ack packet");
|
||||
}
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
}
|
||||
@@ -322,7 +317,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -335,6 +330,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
ctx->bluetooth = SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id);
|
||||
ctx->start_time = SDL_GetTicks();
|
||||
ctx->sequence = 1;
|
||||
ctx->has_color_led = ControllerHasColorLED(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_trigger_rumble = ControllerHasTriggerRumble(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id);
|
||||
@@ -426,17 +422,44 @@ HIDAPI_DriverXboxOne_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst
|
||||
return HIDAPI_DriverXboxOne_UpdateRumble(device);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXboxOne_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXboxOne_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
if (ctx->has_trigger_rumble) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
|
||||
if (ctx->has_color_led) {
|
||||
result |= SDL_JOYCAP_LED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||
|
||||
if (ctx->has_color_led) {
|
||||
Uint8 led_packet[] = { 0x0E, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
led_packet[5] = 0x00; /* Whiteness? Sets white intensity when RGB is 0, seems additive */
|
||||
led_packet[6] = red;
|
||||
led_packet[7] = green;
|
||||
led_packet[8] = blue;
|
||||
|
||||
if (SDL_HIDAPI_SendRumble(device, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_SetError("Couldn't send LED packet");
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -508,12 +531,16 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
Paddle bits:
|
||||
P3: 0x01 (A) P1: 0x02 (B)
|
||||
P4: 0x04 (X) P2: 0x08 (Y)
|
||||
Xbox One Elite Series 2 report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default
|
||||
Xbox One Elite Series 2 4.x firmware report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default
|
||||
Paddle bits:
|
||||
P3: 0x04 (A) P1: 0x01 (B)
|
||||
P4: 0x08 (X) P2: 0x02 (Y)
|
||||
Xbox One Elite Series 2 5.x firmware report is 50 bytes, paddles in data[22], mode in data[23], mode 0 has no mapped paddles by default
|
||||
Paddle bits:
|
||||
P3: 0x04 (A) P1: 0x01 (B)
|
||||
P4: 0x08 (X) P2: 0x02 (Y)
|
||||
*/
|
||||
if (ctx->has_paddles && (size == 33 || size == 38)) {
|
||||
if (ctx->has_paddles && (size == 33 || size == 38 || size == 50)) {
|
||||
int paddle_index;
|
||||
int button1_bit;
|
||||
int button2_bit;
|
||||
@@ -532,7 +559,7 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
/* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */
|
||||
paddles_mapped = (SDL_memcmp(&data[4], &data[18], 2) != 0);
|
||||
|
||||
} else /* if (size == 38) */ {
|
||||
} else if (size == 38) {
|
||||
/* XBox One Elite Series 2 */
|
||||
paddle_index = 18;
|
||||
button1_bit = 0x01;
|
||||
@@ -540,6 +567,15 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
button3_bit = 0x04;
|
||||
button4_bit = 0x08;
|
||||
paddles_mapped = (data[19] != 0);
|
||||
|
||||
} else /* if (size == 50) */{
|
||||
/* XBox One Elite Series 2 */
|
||||
paddle_index = 22;
|
||||
button1_bit = 0x01;
|
||||
button2_bit = 0x02;
|
||||
button3_bit = 0x04;
|
||||
button4_bit = 0x08;
|
||||
paddles_mapped = (data[23] != 0);
|
||||
}
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n",
|
||||
@@ -595,6 +631,14 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXboxOne_HandleStatusPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
@@ -627,8 +671,10 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_Driver
|
||||
|
||||
/*
|
||||
* Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux)
|
||||
* Xbox One S with firmware 5.x uses a 17 byte packet with BACK and GUIDE buttons in byte 15
|
||||
* Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet
|
||||
* Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet
|
||||
* Xbox One Elite Series 2 with firmware 5.11.3112 uses a 19 byte packet with BACK and GUIDE buttons in byte 15
|
||||
* Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17
|
||||
*/
|
||||
static void
|
||||
@@ -644,10 +690,7 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb
|
||||
}
|
||||
|
||||
if (ctx->last_state[15] != data[15]) {
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else if (!ctx->has_guide_packet) {
|
||||
if (!ctx->has_guide_packet) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
@@ -655,12 +698,11 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (ctx->last_state[16] != data[16]) {
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, ((data[15] & 0x04) || (data[16] & 0x01)) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -727,8 +769,13 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv
|
||||
if (size == 16) {
|
||||
/* Original Xbox One S, with separate report for guide button */
|
||||
HIDAPI_DriverXboxOneBluetooth_HandleButtons16(joystick, ctx, data, size);
|
||||
} else {
|
||||
} else if (size > 16) {
|
||||
HIDAPI_DriverXboxOneBluetooth_HandleButtons(joystick, ctx, data, size);
|
||||
} else {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
SDL_Log("Unknown Bluetooth state packet format\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->last_state[13] != data[13]) {
|
||||
@@ -908,7 +955,7 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
int size;
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -961,16 +1008,18 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
is firmware version 5.5.2641.0, and product version 0x0505 = 1285
|
||||
then 8 bytes of unknown data
|
||||
*/
|
||||
if (data[1] == 0x20) {
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
||||
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
||||
#endif
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
||||
} else {
|
||||
/* Possibly an announce from a device plugged into the controller */
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
/* Controller heartbeat */
|
||||
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
||||
}
|
||||
/* Controller status update */
|
||||
HIDAPI_DriverXboxOne_HandleStatusPacket(joystick, ctx, data, size);
|
||||
break;
|
||||
case 0x04:
|
||||
/* Unknown chatty controller information, sent by both sides */
|
||||
@@ -1060,7 +1109,7 @@ HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
|
||||
{
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1078,6 +1127,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXboxOne_IsSupportedDevice,
|
||||
HIDAPI_DriverXboxOne_GetDeviceName,
|
||||
HIDAPI_DriverXboxOne_InitDevice,
|
||||
@@ -1087,7 +1137,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
|
||||
HIDAPI_DriverXboxOne_OpenJoystick,
|
||||
HIDAPI_DriverXboxOne_RumbleJoystick,
|
||||
HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXboxOne_HasJoystickLED,
|
||||
HIDAPI_DriverXboxOne_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXboxOne_SetJoystickLED,
|
||||
HIDAPI_DriverXboxOne_SendJoystickEffect,
|
||||
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
|
||||
|
@@ -25,52 +25,17 @@
|
||||
#include "SDL_atomic.h"
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_log.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hidapijoystick_c.h"
|
||||
#include "SDL_hidapi_rumble.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../windows/SDL_rawinputjoystick_c.h"
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <mach/mach.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hid/IOHIDDevice.h>
|
||||
#include <IOKit/usb/USBSpec.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#include <unistd.h> /* just in case we didn't use that SDL_USE_LIBUDEV block... */
|
||||
#include <errno.h> /* errno, strerror */
|
||||
#include <fcntl.h>
|
||||
#include <limits.h> /* For the definition of NAME_MAX */
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
typedef enum
|
||||
{
|
||||
ENUMERATION_UNSET,
|
||||
ENUMERATION_LIBUDEV,
|
||||
ENUMERATION_FALLBACK
|
||||
} LinuxEnumerationMethod;
|
||||
|
||||
static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET;
|
||||
#endif
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
@@ -109,434 +74,12 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
|
||||
};
|
||||
static int SDL_HIDAPI_numdrivers = 0;
|
||||
static SDL_SpinLock SDL_HIDAPI_spinlock;
|
||||
static Uint32 SDL_HIDAPI_change_count = 0;
|
||||
static SDL_HIDAPI_Device *SDL_HIDAPI_devices;
|
||||
static int SDL_HIDAPI_numjoysticks = 0;
|
||||
static SDL_bool initialized = SDL_FALSE;
|
||||
static SDL_bool shutting_down = SDL_FALSE;
|
||||
|
||||
#if defined(HAVE_INOTIFY)
|
||||
static int inotify_fd = -1;
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
static const SDL_UDEV_Symbols * usyms = NULL;
|
||||
#endif
|
||||
|
||||
static struct
|
||||
{
|
||||
SDL_bool m_bHaveDevicesChanged;
|
||||
SDL_bool m_bCanGetNotifications;
|
||||
Uint32 m_unLastDetect;
|
||||
|
||||
#if defined(__WIN32__)
|
||||
SDL_threadID m_nThreadID;
|
||||
WNDCLASSEXA m_wndClass;
|
||||
HWND m_hwndMsg;
|
||||
HDEVNOTIFY m_hNotify;
|
||||
double m_flLastWin32MessageCheck;
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
IONotificationPortRef m_notificationPort;
|
||||
mach_port_t m_notificationMach;
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
struct udev *m_pUdev;
|
||||
struct udev_monitor *m_pUdevMonitor;
|
||||
int m_nUdevFd;
|
||||
#endif
|
||||
} SDL_HIDAPI_discovery;
|
||||
|
||||
|
||||
#ifdef __WIN32__
|
||||
struct _DEV_BROADCAST_HDR
|
||||
{
|
||||
DWORD dbch_size;
|
||||
DWORD dbch_devicetype;
|
||||
DWORD dbch_reserved;
|
||||
};
|
||||
|
||||
typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A
|
||||
{
|
||||
DWORD dbcc_size;
|
||||
DWORD dbcc_devicetype;
|
||||
DWORD dbcc_reserved;
|
||||
GUID dbcc_classguid;
|
||||
char dbcc_name[ 1 ];
|
||||
} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A;
|
||||
|
||||
typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
|
||||
#define DBT_DEVICEARRIVAL 0x8000 /* system detected a new device */
|
||||
#define DBT_DEVICEREMOVECOMPLETE 0x8004 /* device was removed from the system */
|
||||
#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 /* device interface class */
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#define DBT_CONFIGCHANGED 0x0018
|
||||
#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */
|
||||
#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */
|
||||
|
||||
#include <initguid.h>
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
|
||||
|
||||
static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_DEVICECHANGE:
|
||||
switch (wParam) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator)
|
||||
{
|
||||
/* Must drain the iterator, or we won't receive new notifications */
|
||||
io_object_t entry;
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
*(SDL_bool*)context = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* __MACOSX__ */
|
||||
|
||||
#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)
|
||||
{
|
||||
return (SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
StrIsInteger(const char *string)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (*string == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = string; *p != '\0'; p++) {
|
||||
if (*p < '0' || *p > '9') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
HIDAPI_InitializeDiscovery()
|
||||
{
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_FALSE;
|
||||
SDL_HIDAPI_discovery.m_unLastDetect = 0;
|
||||
|
||||
#if defined(__WIN32__)
|
||||
SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID();
|
||||
|
||||
SDL_zero(SDL_HIDAPI_discovery.m_wndClass);
|
||||
SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL);
|
||||
SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION";
|
||||
SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */
|
||||
SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass);
|
||||
SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
|
||||
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast;
|
||||
|
||||
SDL_zero(devBroadcast);
|
||||
devBroadcast.dbcc_size = sizeof( devBroadcast );
|
||||
devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
||||
|
||||
/* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored,
|
||||
* but that seems to be necessary to get a notice after each individual usb input device actually
|
||||
* installs, rather than just as the composite device is seen.
|
||||
*/
|
||||
SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification( SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES );
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = ( SDL_HIDAPI_discovery.m_hNotify != 0 );
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
{
|
||||
io_iterator_t portIterator = 0;
|
||||
io_object_t entry;
|
||||
IOReturn result = IOServiceAddMatchingNotification(
|
||||
SDL_HIDAPI_discovery.m_notificationPort,
|
||||
kIOFirstMatchNotification,
|
||||
IOServiceMatching(kIOHIDDeviceKey),
|
||||
CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator);
|
||||
|
||||
if (result == 0) {
|
||||
/* Must drain the existing iterator, or we won't receive new notifications */
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
}
|
||||
} else {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
SDL_HIDAPI_discovery.m_notificationPort = nil;
|
||||
}
|
||||
}
|
||||
{
|
||||
io_iterator_t portIterator = 0;
|
||||
io_object_t entry;
|
||||
IOReturn result = IOServiceAddMatchingNotification(
|
||||
SDL_HIDAPI_discovery.m_notificationPort,
|
||||
kIOTerminatedNotification,
|
||||
IOServiceMatching(kIOHIDDeviceKey),
|
||||
CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator);
|
||||
|
||||
if (result == 0) {
|
||||
/* Must drain the existing iterator, or we won't receive new notifications */
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
}
|
||||
} else {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
SDL_HIDAPI_discovery.m_notificationPort = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL;
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL);
|
||||
|
||||
#endif // __MACOSX__
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
SDL_HIDAPI_discovery.m_pUdev = NULL;
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = -1;
|
||||
|
||||
usyms = SDL_UDEV_GetUdevSyms();
|
||||
if (usyms) {
|
||||
SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new();
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
{
|
||||
#if defined(HAVE_INOTIFY)
|
||||
inotify_fd = SDL_inotify_init1();
|
||||
|
||||
if (inotify_fd < 0) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
|
||||
"Unable to initialize inotify, falling back to polling: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to watch for attribute changes in addition to
|
||||
* creation, because when a device is first created, it has
|
||||
* permissions that we can't read. When udev chmods it to
|
||||
* something that we maybe *can* read, we'll get an
|
||||
* IN_ATTRIB event to tell us. */
|
||||
if (inotify_add_watch(inotify_fd, "/dev",
|
||||
IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) {
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
|
||||
"Unable to add inotify watch, falling back to polling: %s",
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
|
||||
#endif /* HAVE_INOTIFY */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_UpdateDiscovery()
|
||||
{
|
||||
if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) {
|
||||
const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
|
||||
Uint32 now = SDL_GetTicks();
|
||||
if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
SDL_HIDAPI_discovery.m_unLastDetect = now;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */
|
||||
/* We'll only get messages on the same thread that created the window */
|
||||
if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) {
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) {
|
||||
if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
struct { mach_msg_header_t hdr; char payload[ 4096 ]; } msg;
|
||||
while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) {
|
||||
IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) {
|
||||
/* Drain all notification events.
|
||||
* We don't expect a lot of device notifications so just
|
||||
* do a new discovery on any kind or number of notifications.
|
||||
* This could be made more restrictive if necessary.
|
||||
*/
|
||||
for (;;) {
|
||||
struct pollfd PollUdev;
|
||||
struct udev_device *pUdevDevice;
|
||||
|
||||
PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd;
|
||||
PollUdev.events = POLLIN;
|
||||
if (poll(&PollUdev, 1, 0) != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
if (pUdevDevice) {
|
||||
const char *action = NULL;
|
||||
action = usyms->udev_device_get_action(pUdevDevice);
|
||||
if (!action || SDL_strcmp(action, "add") == 0 || SDL_strcmp(action, "remove") == 0) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
}
|
||||
usyms->udev_device_unref(pUdevDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
{
|
||||
#if defined(HAVE_INOTIFY)
|
||||
if (inotify_fd >= 0) {
|
||||
union
|
||||
{
|
||||
struct inotify_event event;
|
||||
char storage[4096];
|
||||
char enough_for_inotify[sizeof (struct inotify_event) + NAME_MAX + 1];
|
||||
} buf;
|
||||
ssize_t bytes;
|
||||
size_t remain = 0;
|
||||
size_t len;
|
||||
|
||||
bytes = read(inotify_fd, &buf, sizeof (buf));
|
||||
|
||||
if (bytes > 0) {
|
||||
remain = (size_t) bytes;
|
||||
}
|
||||
|
||||
while (remain > 0) {
|
||||
if (buf.event.len > 0 &&
|
||||
!SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
|
||||
if (StrHasPrefix(buf.event.name, "hidraw") &&
|
||||
StrIsInteger(buf.event.name + strlen ("hidraw"))) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
/* We found an hidraw change. We still continue to
|
||||
* drain the inotify fd to avoid leaving old
|
||||
* notifications in the queue. */
|
||||
}
|
||||
}
|
||||
|
||||
len = sizeof (struct inotify_event) + buf.event.len;
|
||||
remain -= len;
|
||||
|
||||
if (remain != 0) {
|
||||
memmove(&buf.storage[0], &buf.storage[len], remain);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INOTIFY */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_ShutdownDiscovery()
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
if (SDL_HIDAPI_discovery.m_hNotify)
|
||||
UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify);
|
||||
|
||||
if (SDL_HIDAPI_discovery.m_hwndMsg) {
|
||||
DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg);
|
||||
}
|
||||
|
||||
UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance);
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV &&
|
||||
usyms) {
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev);
|
||||
}
|
||||
SDL_UDEV_ReleaseUdevSyms();
|
||||
usyms = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size)
|
||||
{
|
||||
@@ -658,8 +201,7 @@ static void
|
||||
HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
if (device->driver) {
|
||||
/* Already setup */
|
||||
return;
|
||||
return; /* Already setup */
|
||||
}
|
||||
|
||||
device->driver = HIDAPI_GetDeviceDriver(device);
|
||||
@@ -681,8 +223,7 @@ static void
|
||||
HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
if (!device->driver) {
|
||||
/* Already cleaned up */
|
||||
return;
|
||||
return; /* Already cleaned up */
|
||||
}
|
||||
|
||||
/* Disconnect any joysticks */
|
||||
@@ -767,17 +308,7 @@ HIDAPI_JoystickInit(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
|
||||
/* The hidapi framwork is weak-linked on Apple platforms */
|
||||
int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import));
|
||||
|
||||
if (hid_init == NULL) {
|
||||
SDL_SetError("Couldn't initialize hidapi, framework not available");
|
||||
return -1;
|
||||
}
|
||||
#endif /* __MACOSX__ || __IPHONEOS__ || __TVOS__ */
|
||||
|
||||
if (hid_init() < 0) {
|
||||
if (SDL_hid_init() < 0) {
|
||||
SDL_SetError("Couldn't initialize hidapi");
|
||||
return -1;
|
||||
}
|
||||
@@ -788,7 +319,6 @@ HIDAPI_JoystickInit(void)
|
||||
}
|
||||
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
|
||||
SDL_HIDAPIDriverHintChanged, NULL);
|
||||
HIDAPI_InitializeDiscovery();
|
||||
HIDAPI_JoystickDetect();
|
||||
HIDAPI_UpdateDevices();
|
||||
|
||||
@@ -863,10 +393,13 @@ HIDAPI_ConvertString(const wchar_t *wide_string)
|
||||
if (wide_string) {
|
||||
string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
if (!string) {
|
||||
if (sizeof(wchar_t) == sizeof(Uint16)) {
|
||||
switch (sizeof(wchar_t)) {
|
||||
case 2:
|
||||
string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
} else if (sizeof(wchar_t) == sizeof(Uint32)) {
|
||||
break;
|
||||
case 4:
|
||||
string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -874,7 +407,7 @@ HIDAPI_ConvertString(const wchar_t *wide_string)
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
HIDAPI_AddDevice(struct SDL_hid_device_info *info)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
SDL_HIDAPI_Device *curr, *last = NULL;
|
||||
@@ -1038,7 +571,7 @@ static void
|
||||
HIDAPI_UpdateDeviceList(void)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
struct hid_device_info *devs, *info;
|
||||
struct SDL_hid_device_info *devs, *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
@@ -1051,7 +584,7 @@ HIDAPI_UpdateDeviceList(void)
|
||||
|
||||
/* Enumerate the devices */
|
||||
if (SDL_HIDAPI_numdrivers > 0) {
|
||||
devs = hid_enumerate(0, 0);
|
||||
devs = SDL_hid_enumerate(0, 0);
|
||||
if (devs) {
|
||||
for (info = devs; info; info = info->next) {
|
||||
device = HIDAPI_GetJoystickByInfo(info->path, info->vendor_id, info->product_id);
|
||||
@@ -1061,7 +594,7 @@ HIDAPI_UpdateDeviceList(void)
|
||||
HIDAPI_AddDevice(info);
|
||||
}
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
SDL_hid_free_enumeration(devs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1202,11 +735,10 @@ static void
|
||||
HIDAPI_JoystickDetect(void)
|
||||
{
|
||||
if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) {
|
||||
HIDAPI_UpdateDiscovery();
|
||||
if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
|
||||
/* FIXME: We probably need to schedule an update in a few seconds as well */
|
||||
Uint32 count = SDL_hid_device_change_count();
|
||||
if (SDL_HIDAPI_change_count != count) {
|
||||
HIDAPI_UpdateDeviceList();
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_FALSE;
|
||||
SDL_HIDAPI_change_count = count;
|
||||
}
|
||||
SDL_AtomicUnlock(&SDL_HIDAPI_spinlock);
|
||||
}
|
||||
@@ -1363,15 +895,15 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
||||
return result;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_bool result = SDL_FALSE;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||
|
||||
result = device->driver->HasJoystickLED(device, joystick);
|
||||
result = device->driver->GetJoystickCapabilities(device, joystick);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1470,17 +1002,8 @@ HIDAPI_JoystickQuit(void)
|
||||
|
||||
shutting_down = SDL_TRUE;
|
||||
|
||||
HIDAPI_ShutdownDiscovery();
|
||||
|
||||
SDL_HIDAPI_QuitRumble();
|
||||
|
||||
#if defined(HAVE_INOTIFY)
|
||||
if (inotify_fd >= 0) {
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (SDL_HIDAPI_devices) {
|
||||
HIDAPI_DelDevice(SDL_HIDAPI_devices);
|
||||
}
|
||||
@@ -1495,7 +1018,7 @@ HIDAPI_JoystickQuit(void)
|
||||
SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
|
||||
SDL_HIDAPIDriverHintChanged, NULL);
|
||||
|
||||
hid_exit();
|
||||
SDL_hid_exit();
|
||||
|
||||
shutting_down = SDL_FALSE;
|
||||
initialized = SDL_FALSE;
|
||||
@@ -1520,7 +1043,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
|
||||
HIDAPI_JoystickOpen,
|
||||
HIDAPI_JoystickRumble,
|
||||
HIDAPI_JoystickRumbleTriggers,
|
||||
HIDAPI_JoystickHasLED,
|
||||
HIDAPI_JoystickGetCapabilities,
|
||||
HIDAPI_JoystickSetLED,
|
||||
HIDAPI_JoystickSendEffect,
|
||||
HIDAPI_JoystickSetSensorsEnabled,
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_gamecontroller.h"
|
||||
#include "../../hidapi/hidapi/hidapi.h"
|
||||
#include "SDL_hidapi.h"
|
||||
#include "../usb_ids.h"
|
||||
|
||||
/* This is the full set of HIDAPI drivers available */
|
||||
@@ -70,7 +70,7 @@ typedef struct _SDL_HIDAPI_Device
|
||||
struct _SDL_HIDAPI_DeviceDriver *driver;
|
||||
void *context;
|
||||
SDL_mutex *dev_lock;
|
||||
hid_device *dev;
|
||||
SDL_hid_device *dev;
|
||||
SDL_atomic_t rumble_pending;
|
||||
int num_joysticks;
|
||||
SDL_JoystickID *joysticks;
|
||||
@@ -88,6 +88,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
||||
{
|
||||
const char *hint;
|
||||
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)(Uint16 vendor_id, Uint16 product_id);
|
||||
SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device);
|
||||
@@ -97,7 +98,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
||||
SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
|
||||
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
|
||||
int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size);
|
||||
int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
|
||||
|
@@ -23,6 +23,43 @@
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define HID_FEATURE_REPORT_BYTES 64
|
||||
|
||||
// Header for all host <==> target messages
|
||||
typedef struct
|
||||
{
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
} FeatureReportHeader;
|
||||
|
||||
// Generic controller attribute structure
|
||||
typedef struct
|
||||
{
|
||||
unsigned char attributeTag;
|
||||
uint32_t attributeValue;
|
||||
} ControllerAttribute;
|
||||
|
||||
// Generic controller settings structure
|
||||
typedef struct
|
||||
{
|
||||
ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
|
||||
} MsgGetAttributes;
|
||||
|
||||
|
||||
// This is the only message struct that application code should use to interact with feature request messages. Any new
|
||||
// messages should be added to the union. The structures defined here should correspond to the ones defined in
|
||||
// ValveDeviceCore.cpp.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
FeatureReportHeader header;
|
||||
union
|
||||
{
|
||||
MsgGetAttributes getAttributes;
|
||||
} payload;
|
||||
|
||||
} FeatureReportMsg;
|
||||
|
||||
// Roll this version forward anytime that you are breaking compatibility of existing
|
||||
// message types within ValveInReport_t or the header itself. Hopefully this should
|
||||
// be super rare and instead you shoudl just add new message payloads to the union,
|
||||
|
@@ -298,10 +298,10 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
|
||||
subtype = 1;
|
||||
} else if (device->has_xbox_share_button) {
|
||||
/* Assume Xbox Series X Controller unless/until GCController flows VID/PID */
|
||||
product = USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH;
|
||||
product = USB_PRODUCT_XBOX_SERIES_X_BLE;
|
||||
subtype = 1;
|
||||
} else {
|
||||
/* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
|
||||
/* Assume Xbox One S Bluetooth Controller unless/until GCController flows VID/PID */
|
||||
product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH;
|
||||
subtype = 0;
|
||||
}
|
||||
@@ -652,7 +652,7 @@ IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
IOS_JoystickGetDeviceGUID( int device_index )
|
||||
IOS_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
|
||||
SDL_JoystickGUID guid;
|
||||
@@ -783,9 +783,9 @@ IOS_AccelerometerUpdate(SDL_Joystick *joystick)
|
||||
*/
|
||||
|
||||
/* clamp the data */
|
||||
accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
|
||||
accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
|
||||
accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
|
||||
accel.x = SDL_clamp(accel.x, -maxgforce, maxgforce);
|
||||
accel.y = SDL_clamp(accel.y, -maxgforce, maxgforce);
|
||||
accel.z = SDL_clamp(accel.z, -maxgforce, maxgforce);
|
||||
|
||||
/* pass in data mapped to range of SInt16 */
|
||||
SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
|
||||
@@ -1085,13 +1085,17 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
|
||||
|
||||
-(void)cleanup
|
||||
{
|
||||
if (self.player != nil) {
|
||||
[self.player cancelAndReturnError:nil];
|
||||
self.player = nil;
|
||||
}
|
||||
if (self.engine != nil) {
|
||||
[self.engine stopWithCompletionHandler:nil];
|
||||
self.engine = nil;
|
||||
@autoreleasepool {
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (self.player != nil) {
|
||||
[self.player cancelAndReturnError:nil];
|
||||
self.player = nil;
|
||||
}
|
||||
if (self.engine != nil) {
|
||||
[self.engine stopWithCompletionHandler:nil];
|
||||
self.engine = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1268,6 +1272,10 @@ IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
|
||||
#ifdef ENABLE_MFI_RUMBLE
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1294,6 +1302,10 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
||||
#ifdef ENABLE_MFI_RUMBLE
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1314,22 +1326,43 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
||||
#endif
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
IOS_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
IOS_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
Uint32 result = 0;
|
||||
|
||||
#if defined(ENABLE_MFI_LIGHT) || defined(ENABLE_MFI_RUMBLE)
|
||||
@autoreleasepool {
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCDeviceLight *light = controller.light;
|
||||
if (light) {
|
||||
return SDL_TRUE;
|
||||
GCController *controller = device->controller;
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
if (controller.light) {
|
||||
result |= SDL_JOYCAP_LED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MFI_RUMBLE
|
||||
if (controller.haptics) {
|
||||
for (GCHapticsLocality locality in controller.haptics.supportedLocalities) {
|
||||
if ([locality isEqualToString:GCHapticsLocalityHandles]) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
} else if ([locality isEqualToString:GCHapticsLocalityTriggers]) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_MFI_LIGHT */
|
||||
#endif /* ENABLE_MFI_LIGHT || ENABLE_MFI_RUMBLE */
|
||||
|
||||
return SDL_FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1337,8 +1370,14 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
#ifdef ENABLE_MFI_LIGHT
|
||||
@autoreleasepool {
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCController *controller = device->controller;
|
||||
GCDeviceLight *light = controller.light;
|
||||
if (light) {
|
||||
light.color = [[GCColor alloc] initWithRed:(float)red / 255.0f
|
||||
@@ -1364,8 +1403,14 @@ IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
#ifdef ENABLE_MFI_SENSORS
|
||||
@autoreleasepool {
|
||||
SDL_JoystickDeviceItem *device = joystick->hwdata;
|
||||
|
||||
if (device == NULL) {
|
||||
return SDL_SetError("Controller is no longer connected");
|
||||
}
|
||||
|
||||
if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
GCController *controller = joystick->hwdata->controller;
|
||||
GCController *controller = device->controller;
|
||||
GCMotion *motion = controller.motion;
|
||||
if (motion) {
|
||||
motion.sensorsActive = enabled ? YES : NO;
|
||||
@@ -1428,7 +1473,6 @@ IOS_JoystickClose(SDL_Joystick *joystick)
|
||||
|
||||
#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE
|
||||
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];
|
||||
if ([button isBoundToSystemGesture]) {
|
||||
@@ -1491,12 +1535,223 @@ IOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device)
|
||||
{
|
||||
if (is_macos11()) {
|
||||
return [GCController supportsHIDDevice:device] ? SDL_TRUE : SDL_FALSE;
|
||||
if ([GCController supportsHIDDevice:device]) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* GCController supportsHIDDevice may return false if the device hasn't been
|
||||
* seen by the framework yet, so check a few controllers we know are supported.
|
||||
*/
|
||||
{
|
||||
Sint32 vendor = 0;
|
||||
Sint32 product = 0;
|
||||
CFTypeRef refCF = NULL;
|
||||
|
||||
refCF = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
|
||||
if (refCF) {
|
||||
CFNumberGetValue(refCF, kCFNumberSInt32Type, &vendor);
|
||||
}
|
||||
|
||||
refCF = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
|
||||
if (refCF) {
|
||||
CFNumberGetValue(refCF, kCFNumberSInt32Type, &product);
|
||||
}
|
||||
|
||||
if (vendor == USB_VENDOR_MICROSOFT && SDL_IsJoystickXboxSeriesX(vendor, product)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
|
||||
static void
|
||||
GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name)
|
||||
{
|
||||
if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) {
|
||||
if (element) {
|
||||
[element.sfSymbolsName getCString: name maxLength: 255 encoding: NSASCIIStringEncoding];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GCControllerDirectionPad *
|
||||
GetDirectionalPadForController(GCController *controller)
|
||||
{
|
||||
if (controller.extendedGamepad) {
|
||||
return controller.extendedGamepad.dpad;
|
||||
}
|
||||
|
||||
if (controller.gamepad) {
|
||||
return controller.gamepad.dpad;
|
||||
}
|
||||
|
||||
if (controller.microGamepad) {
|
||||
return controller.microGamepad.dpad;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
#endif /* SDL_JOYSTICK_MFI && ENABLE_PHYSICAL_INPUT_PROFILE */
|
||||
|
||||
static char elementName[256];
|
||||
|
||||
const char *
|
||||
IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
|
||||
{
|
||||
elementName[0] = '\0';
|
||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
|
||||
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
|
||||
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;
|
||||
switch (button)
|
||||
{
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonA], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonB], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonX], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonY], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonOptions], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_GUIDE:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonHome], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputButtonMenu], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSTICK:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstickButton], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstickButton], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputLeftShoulder], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputRightShoulder], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP: {
|
||||
GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller);
|
||||
if (dpad) {
|
||||
GetAppleSFSymbolsNameForElement(dpad.up, elementName);
|
||||
if (SDL_strlen(elementName) == 0) {
|
||||
SDL_strlcpy(elementName, "dpad.up.fill", sizeof(elementName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: {
|
||||
GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller);
|
||||
if (dpad) {
|
||||
GetAppleSFSymbolsNameForElement(dpad.down, elementName);
|
||||
if (SDL_strlen(elementName) == 0) {
|
||||
SDL_strlcpy(elementName, "dpad.down.fill", sizeof(elementName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: {
|
||||
GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller);
|
||||
if (dpad) {
|
||||
GetAppleSFSymbolsNameForElement(dpad.left, elementName);
|
||||
if (SDL_strlen(elementName) == 0) {
|
||||
SDL_strlcpy(elementName, "dpad.left.fill", sizeof(elementName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: {
|
||||
GCControllerDirectionPad * dpad = GetDirectionalPadForController(controller);
|
||||
if (dpad) {
|
||||
GetAppleSFSymbolsNameForElement(dpad.right, elementName);
|
||||
if (SDL_strlen(elementName) == 0) {
|
||||
SDL_strlcpy(elementName, "dpad.right.fill", sizeof(elementName));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLER_BUTTON_MISC1:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_PADDLE1:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleOne], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_PADDLE2:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleTwo], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_PADDLE3:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleThree], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_PADDLE4:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleFour], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_TOUCHPAD:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return elementName;
|
||||
}
|
||||
|
||||
const char *
|
||||
IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
|
||||
{
|
||||
elementName[0] = '\0';
|
||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
|
||||
if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) {
|
||||
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;
|
||||
switch (axis)
|
||||
{
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputLeftTrigger], elementName);
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
GetAppleSFSymbolsNameForElement(elements[GCInputRightTrigger], elementName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return *elementName ? elementName : NULL;
|
||||
}
|
||||
|
||||
|
||||
SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
||||
{
|
||||
IOS_JoystickInit,
|
||||
@@ -1510,7 +1765,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
|
||||
IOS_JoystickOpen,
|
||||
IOS_JoystickRumble,
|
||||
IOS_JoystickRumbleTriggers,
|
||||
IOS_JoystickHasLED,
|
||||
IOS_JoystickGetCapabilities,
|
||||
IOS_JoystickSetLED,
|
||||
IOS_JoystickSendEffect,
|
||||
IOS_JoystickSetSensorsEnabled,
|
||||
|
475
externals/SDL/src/joystick/linux/SDL_sysjoystick.c
vendored
475
externals/SDL/src/joystick/linux/SDL_sysjoystick.c
vendored
@@ -56,6 +56,12 @@
|
||||
#ifndef SYN_DROPPED
|
||||
#define SYN_DROPPED 3
|
||||
#endif
|
||||
#ifndef BTN_NORTH
|
||||
#define BTN_NORTH 0x133
|
||||
#endif
|
||||
#ifndef BTN_WEST
|
||||
#define BTN_WEST 0x134
|
||||
#endif
|
||||
#ifndef BTN_DPAD_UP
|
||||
#define BTN_DPAD_UP 0x220
|
||||
#endif
|
||||
@@ -85,6 +91,7 @@ typedef enum
|
||||
|
||||
static EnumerationMethod enumeration_method = ENUMERATION_UNSET;
|
||||
|
||||
static SDL_bool IsJoystickJSNode(const char *node);
|
||||
static int MaybeAddDevice(const char *path);
|
||||
static int MaybeRemoveDevice(const char *path);
|
||||
|
||||
@@ -105,6 +112,7 @@ typedef struct SDL_joylist_item
|
||||
SDL_GamepadMapping *mapping;
|
||||
} SDL_joylist_item;
|
||||
|
||||
static SDL_bool SDL_classic_joysticks = SDL_FALSE;
|
||||
static SDL_joylist_item *SDL_joylist = NULL;
|
||||
static SDL_joylist_item *SDL_joylist_tail = NULL;
|
||||
static int numjoysticks = 0;
|
||||
@@ -176,24 +184,31 @@ GuessIsJoystick(int fd)
|
||||
}
|
||||
|
||||
static int
|
||||
IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||
IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||
{
|
||||
struct input_id inpid;
|
||||
Uint16 *guid16 = (Uint16 *)guid->data;
|
||||
char *name;
|
||||
char product_string[128];
|
||||
|
||||
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
||||
if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) >= 0) {
|
||||
SDL_zero(inpid);
|
||||
#if SDL_USE_LIBUDEV
|
||||
SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version);
|
||||
#endif
|
||||
} else {
|
||||
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
||||
if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (ioctl(fd, EVIOCGID, &inpid) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
|
||||
return 0;
|
||||
if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
|
||||
@@ -213,7 +228,7 @@ IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||
FixupDeviceInfoForMapping(fd, &inpid);
|
||||
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
||||
SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
||||
#endif
|
||||
|
||||
SDL_memset(guid->data, 0, sizeof(guid->data));
|
||||
@@ -254,6 +269,15 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
|
||||
if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||
return;
|
||||
}
|
||||
if (SDL_classic_joysticks) {
|
||||
if (!IsJoystickJSNode(devpath)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (IsJoystickJSNode(devpath)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
MaybeAddDevice(devpath);
|
||||
break;
|
||||
|
||||
@@ -268,6 +292,15 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
|
||||
}
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
static void
|
||||
FreeJoylistItem(SDL_joylist_item *item)
|
||||
{
|
||||
SDL_free(item->mapping);
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
}
|
||||
|
||||
static int
|
||||
MaybeAddDevice(const char *path)
|
||||
{
|
||||
@@ -293,36 +326,33 @@ MaybeAddDevice(const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
fd = open(path, O_RDONLY | O_CLOEXEC, 0);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Checking %s\n", path);
|
||||
SDL_Log("Checking %s\n", path);
|
||||
#endif
|
||||
|
||||
isstick = IsJoystick(fd, &name, &guid);
|
||||
isstick = IsJoystick(path, fd, &name, &guid);
|
||||
close(fd);
|
||||
if (!isstick) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
|
||||
item = (SDL_joylist_item *) SDL_calloc(1, sizeof (SDL_joylist_item));
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_zerop(item);
|
||||
item->devnum = sb.st_rdev;
|
||||
item->path = SDL_strdup(path);
|
||||
item->name = name;
|
||||
item->guid = guid;
|
||||
|
||||
if ((item->path == NULL) || (item->name == NULL)) {
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
FreeJoylistItem(item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -342,6 +372,31 @@ MaybeAddDevice(const char *path)
|
||||
return numjoysticks;
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev)
|
||||
{
|
||||
if (item->hwdata) {
|
||||
item->hwdata->item = NULL;
|
||||
}
|
||||
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickRemoved(item->device_instance);
|
||||
FreeJoylistItem(item);
|
||||
}
|
||||
|
||||
static int
|
||||
MaybeRemoveDevice(const char *path)
|
||||
{
|
||||
@@ -356,30 +411,7 @@ MaybeRemoveDevice(const char *path)
|
||||
/* found it, remove it. */
|
||||
if (SDL_strcmp(path, item->path) == 0) {
|
||||
const int retval = item->device_instance;
|
||||
if (item->hwdata) {
|
||||
item->hwdata->item = NULL;
|
||||
}
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickRemoved(item->device_instance);
|
||||
|
||||
if (item->mapping) {
|
||||
SDL_free(item->mapping);
|
||||
}
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
RemoveJoylistItem(item, prev);
|
||||
return retval;
|
||||
}
|
||||
prev = item;
|
||||
@@ -396,26 +428,7 @@ HandlePendingRemovals(void)
|
||||
|
||||
while (item != NULL) {
|
||||
if (item->hwdata && item->hwdata->gone) {
|
||||
item->hwdata->item = NULL;
|
||||
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickRemoved(item->device_instance);
|
||||
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
RemoveJoylistItem(item, prev);
|
||||
|
||||
if (prev != NULL) {
|
||||
item = prev->next;
|
||||
@@ -444,9 +457,7 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG
|
||||
item->m_bSteamController = SDL_TRUE;
|
||||
|
||||
if ((item->path == NULL) || (item->name == NULL)) {
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
FreeJoylistItem(item);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -474,26 +485,7 @@ static void SteamControllerDisconnectedCallback(int device_instance)
|
||||
for (item = SDL_joylist; item != NULL; item = item->next) {
|
||||
/* found it, remove it. */
|
||||
if (item->device_instance == device_instance) {
|
||||
if (item->hwdata) {
|
||||
item->hwdata->item = NULL;
|
||||
}
|
||||
if (prev != NULL) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_joylist == item);
|
||||
SDL_joylist = item->next;
|
||||
}
|
||||
if (item == SDL_joylist_tail) {
|
||||
SDL_joylist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the joystick count before we post the event */
|
||||
--numjoysticks;
|
||||
|
||||
SDL_PrivateJoystickRemoved(item->device_instance);
|
||||
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
RemoveJoylistItem(item, prev);
|
||||
return;
|
||||
}
|
||||
prev = item;
|
||||
@@ -539,6 +531,36 @@ StrIsInteger(const char *string)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
IsJoystickJSNode(const char *node)
|
||||
{
|
||||
const char *last_slash = SDL_strrchr(node, '/');
|
||||
if (last_slash) {
|
||||
node = last_slash + 1;
|
||||
}
|
||||
return (StrHasPrefix(node, "js") && StrIsInteger(node + 2));
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
IsJoystickEventNode(const char *node)
|
||||
{
|
||||
const char *last_slash = SDL_strrchr(node, '/');
|
||||
if (last_slash) {
|
||||
node = last_slash + 1;
|
||||
}
|
||||
return (StrHasPrefix(node, "event") && StrIsInteger(node + 5));
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
IsJoystickDeviceNode(const char *node)
|
||||
{
|
||||
if (SDL_classic_joysticks) {
|
||||
return IsJoystickJSNode(node);
|
||||
} else {
|
||||
return IsJoystickEventNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LINUX_InotifyJoystickDetect(void)
|
||||
{
|
||||
@@ -551,6 +573,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||
ssize_t bytes;
|
||||
size_t remain = 0;
|
||||
size_t len;
|
||||
char path[PATH_MAX];
|
||||
|
||||
bytes = read(inotify_fd, &buf, sizeof (buf));
|
||||
|
||||
@@ -560,10 +583,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||
|
||||
while (remain > 0) {
|
||||
if (buf.event.len > 0) {
|
||||
if (StrHasPrefix(buf.event.name, "event") &&
|
||||
StrIsInteger(buf.event.name + strlen ("event"))) {
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (IsJoystickDeviceNode(buf.event.name)) {
|
||||
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name);
|
||||
|
||||
if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) {
|
||||
@@ -579,7 +599,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||
remain -= len;
|
||||
|
||||
if (remain != 0) {
|
||||
memmove (&buf.storage[0], &buf.storage[len], remain);
|
||||
SDL_memmove (&buf.storage[0], &buf.storage[len], remain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -592,7 +612,7 @@ LINUX_InotifyJoystickDetect(void)
|
||||
static int
|
||||
filter_entries(const struct dirent *entry)
|
||||
{
|
||||
return (SDL_strlen(entry->d_name) > 5 && SDL_strncmp(entry->d_name, "event", 5) == 0);
|
||||
return IsJoystickDeviceNode(entry->d_name);
|
||||
}
|
||||
static int
|
||||
sort_entries(const struct dirent **a, const struct dirent **b)
|
||||
@@ -659,14 +679,18 @@ LINUX_JoystickDetect(void)
|
||||
static int
|
||||
LINUX_JoystickInit(void)
|
||||
{
|
||||
const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE);
|
||||
|
||||
SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (enumeration_method == ENUMERATION_UNSET) {
|
||||
if (SDL_getenv("SDL_JOYSTICK_DISABLE_UDEV") != NULL) {
|
||||
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
|
||||
|
||||
} 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
|
||||
@@ -674,8 +698,8 @@ LINUX_JoystickInit(void)
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Container detected, disabling udev integration");
|
||||
enumeration_method = ENUMERATION_FALLBACK;
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Using udev for joystick device discovery");
|
||||
enumeration_method = ENUMERATION_LIBUDEV;
|
||||
@@ -684,9 +708,9 @@ LINUX_JoystickInit(void)
|
||||
#endif
|
||||
|
||||
/* First see if the user specified one or more joysticks to use */
|
||||
if (SDL_getenv("SDL_JOYSTICK_DEVICE") != NULL) {
|
||||
if (devices != NULL) {
|
||||
char *envcopy, *envpath, *delim;
|
||||
envcopy = SDL_strdup(SDL_getenv("SDL_JOYSTICK_DEVICE"));
|
||||
envcopy = SDL_strdup(devices);
|
||||
envpath = envcopy;
|
||||
while (envpath != NULL) {
|
||||
delim = SDL_strchr(envpath, ':');
|
||||
@@ -706,6 +730,9 @@ LINUX_JoystickInit(void)
|
||||
last_joy_detect_time = 0;
|
||||
last_input_dir_mtime = 0;
|
||||
|
||||
/* Manually scan first, since we sort by device number and udev doesn't */
|
||||
LINUX_JoystickDetect();
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
@@ -747,9 +774,6 @@ LINUX_JoystickInit(void)
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INOTIFY */
|
||||
|
||||
/* Report all devices currently present */
|
||||
LINUX_JoystickDetect();
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -854,6 +878,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
|
||||
unsigned long relbit[NBITS(REL_MAX)] = { 0 };
|
||||
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);
|
||||
|
||||
/* See if this device uses the new unified event API */
|
||||
@@ -865,7 +890,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
|
||||
if (test_bit(i, keybit)) {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has button: 0x%x\n", i);
|
||||
SDL_Log("Joystick has button: 0x%x\n", i);
|
||||
#endif
|
||||
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
||||
joystick->hwdata->has_key[i] = SDL_TRUE;
|
||||
@@ -875,7 +900,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
for (i = 0; i < BTN_JOYSTICK; ++i) {
|
||||
if (test_bit(i, keybit)) {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has button: 0x%x\n", i);
|
||||
SDL_Log("Joystick has button: 0x%x\n", i);
|
||||
#endif
|
||||
joystick->hwdata->key_map[i] = joystick->nbuttons;
|
||||
joystick->hwdata->has_key[i] = SDL_TRUE;
|
||||
@@ -896,10 +921,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has absolute axis: 0x%.2x\n", i);
|
||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
SDL_Log("Joystick has absolute axis: 0x%.2x\n", i);
|
||||
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->abs_map[i] = joystick->naxes;
|
||||
joystick->hwdata->has_abs[i] = SDL_TRUE;
|
||||
@@ -936,10 +961,10 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
continue;
|
||||
}
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick has hat %d\n", hat_index);
|
||||
printf("Values = { %d, %d, %d, %d, %d }\n",
|
||||
absinfo.value, absinfo.minimum, absinfo.maximum,
|
||||
absinfo.fuzz, absinfo.flat);
|
||||
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;
|
||||
@@ -949,16 +974,76 @@ ConfigJoystick(SDL_Joystick *joystick, int fd)
|
||||
++joystick->nballs;
|
||||
}
|
||||
|
||||
/* Allocate data to keep track of these thingamajigs */
|
||||
if (joystick->nhats > 0) {
|
||||
if (allocate_hatdata(joystick) < 0) {
|
||||
joystick->nhats = 0;
|
||||
} else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) &&
|
||||
(ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) {
|
||||
size_t len;
|
||||
|
||||
joystick->hwdata->classic = SDL_TRUE;
|
||||
|
||||
len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam);
|
||||
joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len);
|
||||
if (joystick->hwdata->key_pam) {
|
||||
if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) {
|
||||
SDL_free(joystick->hwdata->key_pam);
|
||||
joystick->hwdata->key_pam = NULL;
|
||||
key_pam_size = 0;
|
||||
}
|
||||
} else {
|
||||
key_pam_size = 0;
|
||||
}
|
||||
for (i = 0; i < key_pam_size; ++i) {
|
||||
Uint16 code = joystick->hwdata->key_pam[i];
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
SDL_Log("Joystick has button: 0x%x\n", code);
|
||||
#endif
|
||||
joystick->hwdata->key_map[code] = joystick->nbuttons;
|
||||
joystick->hwdata->has_key[code] = SDL_TRUE;
|
||||
++joystick->nbuttons;
|
||||
}
|
||||
|
||||
len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam);
|
||||
joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len);
|
||||
if (joystick->hwdata->abs_pam) {
|
||||
if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) {
|
||||
SDL_free(joystick->hwdata->abs_pam);
|
||||
joystick->hwdata->abs_pam = NULL;
|
||||
abs_pam_size = 0;
|
||||
}
|
||||
} else {
|
||||
abs_pam_size = 0;
|
||||
}
|
||||
for (i = 0; i < abs_pam_size; ++i) {
|
||||
Uint8 code = joystick->hwdata->abs_pam[i];
|
||||
|
||||
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 hat %d\n", hat_index);
|
||||
#endif
|
||||
joystick->hwdata->hats_indices[hat_index] = joystick->nhats++;
|
||||
joystick->hwdata->has_hat[hat_index] = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
SDL_Log("Joystick has absolute axis: 0x%.2x\n", code);
|
||||
#endif
|
||||
joystick->hwdata->abs_map[code] = joystick->naxes;
|
||||
joystick->hwdata->has_abs[code] = SDL_TRUE;
|
||||
++joystick->naxes;
|
||||
}
|
||||
}
|
||||
if (joystick->nballs > 0) {
|
||||
if (allocate_balldata(joystick) < 0) {
|
||||
joystick->nballs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate data to keep track of these thingamajigs */
|
||||
if (joystick->nhats > 0) {
|
||||
if (allocate_hatdata(joystick) < 0) {
|
||||
joystick->nhats = 0;
|
||||
}
|
||||
}
|
||||
if (joystick->nballs > 0) {
|
||||
if (allocate_balldata(joystick) < 0) {
|
||||
joystick->nballs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,6 +1070,7 @@ PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
|
||||
joystick->hwdata->guid = item->guid;
|
||||
joystick->hwdata->effect.id = -1;
|
||||
joystick->hwdata->m_bSteamController = item->m_bSteamController;
|
||||
SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map));
|
||||
SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map));
|
||||
|
||||
if (item->m_bSteamController) {
|
||||
@@ -993,7 +1079,12 @@ PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item)
|
||||
&joystick->naxes,
|
||||
&joystick->nhats);
|
||||
} else {
|
||||
const int fd = open(item->path, O_RDWR, 0);
|
||||
/* Try read-write first, so we can do rumble */
|
||||
int fd = open(item->path, O_RDWR | O_CLOEXEC, 0);
|
||||
if (fd < 0) {
|
||||
/* Try read-only again, at least we'll get events in this case */
|
||||
fd = open(item->path, O_RDONLY | O_CLOEXEC, 0);
|
||||
}
|
||||
if (fd < 0) {
|
||||
return SDL_SetError("Unable to open %s", item->path);
|
||||
}
|
||||
@@ -1099,10 +1190,16 @@ LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
LINUX_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
LINUX_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1123,7 +1220,7 @@ LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
static void
|
||||
HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||
{
|
||||
struct hwdata_hat *the_hat;
|
||||
@@ -1148,14 +1245,14 @@ HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
static void
|
||||
HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value)
|
||||
{
|
||||
stick->hwdata->balls[ball].axis[axis] += value;
|
||||
}
|
||||
|
||||
|
||||
static SDL_INLINE int
|
||||
static int
|
||||
AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
||||
{
|
||||
struct axis_correct *correct;
|
||||
@@ -1189,7 +1286,7 @@ AxisCorrect(SDL_Joystick *joystick, int which, int value)
|
||||
return value;
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
static void
|
||||
PollAllValues(SDL_Joystick *joystick)
|
||||
{
|
||||
struct input_absinfo absinfo;
|
||||
@@ -1207,7 +1304,7 @@ PollAllValues(SDL_Joystick *joystick)
|
||||
absinfo.value = AxisCorrect(joystick, i, absinfo.value);
|
||||
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick : Re-read Axis %d (%d) val= %d\n",
|
||||
SDL_Log("Joystick : Re-read Axis %d (%d) val= %d\n",
|
||||
joystick->hwdata->abs_map[i], i, absinfo.value);
|
||||
#endif
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
@@ -1237,7 +1334,7 @@ PollAllValues(SDL_Joystick *joystick)
|
||||
if (joystick->hwdata->has_key[i]) {
|
||||
const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED;
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Joystick : Re-read Button %d (%d) val= %d\n",
|
||||
SDL_Log("Joystick : Re-read Button %d (%d) val= %d\n",
|
||||
joystick->hwdata->key_map[i], i, value);
|
||||
#endif
|
||||
SDL_PrivateJoystickButton(joystick,
|
||||
@@ -1249,12 +1346,11 @@ PollAllValues(SDL_Joystick *joystick)
|
||||
/* Joyballs are relative input, so there's no poll state. Events only! */
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
static void
|
||||
HandleInputEvents(SDL_Joystick *joystick)
|
||||
{
|
||||
struct input_event events[32];
|
||||
int i, len;
|
||||
int code;
|
||||
int i, len, code;
|
||||
|
||||
if (joystick->hwdata->fresh) {
|
||||
PollAllValues(joystick);
|
||||
@@ -1293,13 +1389,10 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||
HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value);
|
||||
break;
|
||||
default:
|
||||
if (joystick->hwdata->abs_map[code] != 0xFF) {
|
||||
events[i].value =
|
||||
AxisCorrect(joystick, code, events[i].value);
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
joystick->hwdata->abs_map[code],
|
||||
events[i].value);
|
||||
}
|
||||
events[i].value = AxisCorrect(joystick, code, events[i].value);
|
||||
SDL_PrivateJoystickAxis(joystick,
|
||||
joystick->hwdata->abs_map[code],
|
||||
events[i].value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1318,7 +1411,7 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||
switch (code) {
|
||||
case SYN_DROPPED :
|
||||
#ifdef DEBUG_INPUT_EVENTS
|
||||
printf("Event SYN_DROPPED detected\n");
|
||||
SDL_Log("Event SYN_DROPPED detected\n");
|
||||
#endif
|
||||
joystick->hwdata->recovering_from_dropped = SDL_TRUE;
|
||||
break;
|
||||
@@ -1343,6 +1436,48 @@ HandleInputEvents(SDL_Joystick *joystick)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleClassicEvents(SDL_Joystick *joystick)
|
||||
{
|
||||
struct js_event events[32];
|
||||
int i, len, code;
|
||||
|
||||
joystick->hwdata->fresh = SDL_FALSE;
|
||||
while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) {
|
||||
len /= sizeof(events[0]);
|
||||
for (i = 0; i < len; ++i) {
|
||||
switch (events[i].type) {
|
||||
case JS_EVENT_BUTTON:
|
||||
code = joystick->hwdata->key_pam[events[i].number];
|
||||
SDL_PrivateJoystickButton(joystick,
|
||||
joystick->hwdata->key_map[code],
|
||||
events[i].value);
|
||||
break;
|
||||
case JS_EVENT_AXIS:
|
||||
code = joystick->hwdata->abs_pam[events[i].number];
|
||||
switch (code) {
|
||||
case ABS_HAT0X:
|
||||
case ABS_HAT0Y:
|
||||
case ABS_HAT1X:
|
||||
case ABS_HAT1Y:
|
||||
case ABS_HAT2X:
|
||||
case ABS_HAT2Y:
|
||||
case ABS_HAT3X:
|
||||
case ABS_HAT3Y:
|
||||
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],
|
||||
events[i].value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
@@ -1353,7 +1488,11 @@ LINUX_JoystickUpdate(SDL_Joystick *joystick)
|
||||
return;
|
||||
}
|
||||
|
||||
HandleInputEvents(joystick);
|
||||
if (joystick->hwdata->classic) {
|
||||
HandleClassicEvents(joystick);
|
||||
} else {
|
||||
HandleInputEvents(joystick);
|
||||
}
|
||||
|
||||
/* Deliver ball motion updates */
|
||||
for (i = 0; i < joystick->nballs; ++i) {
|
||||
@@ -1384,6 +1523,8 @@ LINUX_JoystickClose(SDL_Joystick *joystick)
|
||||
if (joystick->hwdata->item) {
|
||||
joystick->hwdata->item->hwdata = NULL;
|
||||
}
|
||||
SDL_free(joystick->hwdata->key_pam);
|
||||
SDL_free(joystick->hwdata->abs_pam);
|
||||
SDL_free(joystick->hwdata->hats);
|
||||
SDL_free(joystick->hwdata->balls);
|
||||
SDL_free(joystick->hwdata->fname);
|
||||
@@ -1405,9 +1546,7 @@ LINUX_JoystickQuit(void)
|
||||
|
||||
for (item = SDL_joylist; item; item = next) {
|
||||
next = item->next;
|
||||
SDL_free(item->path);
|
||||
SDL_free(item->name);
|
||||
SDL_free(item);
|
||||
FreeJoylistItem(item);
|
||||
}
|
||||
|
||||
SDL_joylist = SDL_joylist_tail = NULL;
|
||||
@@ -1446,6 +1585,7 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
SDL_OutOfMemory();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
|
||||
|
||||
joystick->hwdata = (struct joystick_hwdata *)
|
||||
SDL_calloc(1, sizeof(*joystick->hwdata));
|
||||
@@ -1484,14 +1624,27 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
out->b.target = joystick->hwdata->key_map[BTN_B];
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_X]) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = joystick->hwdata->key_map[BTN_X];
|
||||
}
|
||||
/* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */
|
||||
if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_SONY) {
|
||||
if (joystick->hwdata->has_key[BTN_WEST]) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = joystick->hwdata->key_map[BTN_WEST];
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_Y]) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = joystick->hwdata->key_map[BTN_Y];
|
||||
if (joystick->hwdata->has_key[BTN_NORTH]) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = joystick->hwdata->key_map[BTN_NORTH];
|
||||
}
|
||||
} else {
|
||||
if (joystick->hwdata->has_key[BTN_X]) {
|
||||
out->x.kind = EMappingKind_Button;
|
||||
out->x.target = joystick->hwdata->key_map[BTN_X];
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_Y]) {
|
||||
out->y.kind = EMappingKind_Button;
|
||||
out->y.target = joystick->hwdata->key_map[BTN_Y];
|
||||
}
|
||||
}
|
||||
|
||||
if (joystick->hwdata->has_key[BTN_SELECT]) {
|
||||
@@ -1552,20 +1705,20 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
out->lefttrigger.target = hat | 0x4;
|
||||
out->righttrigger.target = hat | 0x2;
|
||||
} else {
|
||||
if (joystick->hwdata->has_key[BTN_TL2]) {
|
||||
out->lefttrigger.kind = EMappingKind_Button;
|
||||
out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2];
|
||||
} else if (joystick->hwdata->has_abs[ABS_Z]) {
|
||||
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_key[BTN_TR2]) {
|
||||
out->righttrigger.kind = EMappingKind_Button;
|
||||
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
|
||||
} else if (joystick->hwdata->has_abs[ABS_RZ]) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1643,7 +1796,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
|
||||
LINUX_JoystickOpen,
|
||||
LINUX_JoystickRumble,
|
||||
LINUX_JoystickRumbleTriggers,
|
||||
LINUX_JoystickHasLED,
|
||||
LINUX_JoystickGetCapabilities,
|
||||
LINUX_JoystickSetLED,
|
||||
LINUX_JoystickSendEffect,
|
||||
LINUX_JoystickSetSensorsEnabled,
|
||||
|
@@ -56,6 +56,11 @@ struct joystick_hwdata
|
||||
SDL_bool has_key[KEY_MAX];
|
||||
SDL_bool has_abs[ABS_MAX];
|
||||
|
||||
/* Support for the classic joystick interface */
|
||||
SDL_bool classic;
|
||||
Uint16 *key_pam;
|
||||
Uint8 *abs_pam;
|
||||
|
||||
struct axis_correct
|
||||
{
|
||||
SDL_bool use_deadzones;
|
||||
|
39
externals/SDL/src/joystick/os2/SDL_os2joystick.c
vendored
39
externals/SDL/src/joystick/os2/SDL_os2joystick.c
vendored
@@ -147,7 +147,7 @@ struct _joycfg
|
||||
/* OS/2 Implementation Function Prototypes */
|
||||
static int joyPortOpen(HFILE * hGame);
|
||||
static void joyPortClose(HFILE * hGame);
|
||||
static int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars);
|
||||
static int joyGetData(const char *joyenv, char *name, char stopchar, size_t maxchars);
|
||||
static int joyGetEnv(struct _joycfg * joydata);
|
||||
|
||||
|
||||
@@ -421,13 +421,11 @@ static int OS2_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
int i; /* Generic Counter */
|
||||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
|
||||
if (joystick->hwdata == NULL)
|
||||
joystick->hwdata = (struct joystick_hwdata *) SDL_calloc(1, sizeof(*joystick->hwdata));
|
||||
if (!joystick->hwdata)
|
||||
{
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
/* Reset Hardware Data */
|
||||
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
|
||||
|
||||
/* ShortCut Pointer */
|
||||
index = device_index;
|
||||
@@ -440,14 +438,14 @@ static int OS2_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
if ((i < 2) || i < SYS_JoyData[index].axes)
|
||||
{
|
||||
joystick->hwdata->transaxes[i].offset = ((SDL_JOYSTICK_AXIS_MAX + SDL_JOYSTICK_AXIS_MIN)>>1) - SYS_JoyData[index].axes_med[i];
|
||||
joystick->hwdata->transaxes[i].scale1 = (float)abs((SDL_JOYSTICK_AXIS_MIN/SYS_JoyData[index].axes_min[i]));
|
||||
joystick->hwdata->transaxes[i].scale2 = (float)abs((SDL_JOYSTICK_AXIS_MAX/SYS_JoyData[index].axes_max[i]));
|
||||
joystick->hwdata->transaxes[i].scale1 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MIN/SYS_JoyData[index].axes_min[i]));
|
||||
joystick->hwdata->transaxes[i].scale2 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MAX/SYS_JoyData[index].axes_max[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
joystick->hwdata->transaxes[i].offset = 0;
|
||||
joystick->hwdata->transaxes[i].scale1 = 1.0; /* Just in case */
|
||||
joystick->hwdata->transaxes[i].scale2 = 1.0; /* Just in case */
|
||||
joystick->hwdata->transaxes[i].scale1 = 1.0f; /* Just in case */
|
||||
joystick->hwdata->transaxes[i].scale2 = 1.0f; /* Just in case */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,9 +472,9 @@ static int OS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool OS2_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32 OS2_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int OS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
@@ -567,7 +565,7 @@ static void OS2_JoystickUpdate(SDL_Joystick *joystick)
|
||||
if (SYS_JoyData[index].id == 1) corr = 2;
|
||||
else corr = 0;
|
||||
normbut = 4; /* Number of normal buttons */
|
||||
if (joystick->nbuttons<normbut) normbut = joystick->nbuttons;
|
||||
if (joystick->nbuttons < normbut) normbut = joystick->nbuttons;
|
||||
for (i = corr; (i-corr) < normbut; ++i)
|
||||
{
|
||||
/*
|
||||
@@ -700,7 +698,7 @@ static void joyPortClose(HFILE * hGame)
|
||||
/***************************/
|
||||
static int joyGetEnv(struct _joycfg * joydata)
|
||||
{
|
||||
char *joyenv; /* Pointer to tested character */
|
||||
const char *joyenv; /* Pointer to tested character */
|
||||
char tempnumber[5]; /* Temporary place to put numeric texts */
|
||||
|
||||
joyenv = SDL_getenv("SDL_OS2_JOYSTICK");
|
||||
@@ -711,30 +709,29 @@ static int joyGetEnv(struct _joycfg * joydata)
|
||||
|
||||
/* If the string name starts with '... get if fully */
|
||||
if (*joyenv == '\'') joyenv += joyGetData(++joyenv,joydata->name,'\'',sizeof(joydata->name));
|
||||
|
||||
/* If not, get it until the next space */
|
||||
else if (*joyenv == '\"') joyenv+=joyGetData(++joyenv,joydata->name,'\"',sizeof(joydata->name));
|
||||
else if (*joyenv == '\"') joyenv += joyGetData(++joyenv,joydata->name,'\"',sizeof(joydata->name));
|
||||
else joyenv += joyGetData(joyenv,joydata->name,' ',sizeof(joydata->name));
|
||||
|
||||
/* Now get the number of axes */
|
||||
while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */
|
||||
joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber));
|
||||
joydata->axes = atoi(tempnumber);
|
||||
joydata->axes = SDL_atoi(tempnumber);
|
||||
|
||||
/* Now get the number of buttons */
|
||||
while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */
|
||||
joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber));
|
||||
joydata->buttons = atoi(tempnumber);
|
||||
joydata->buttons = SDL_atoi(tempnumber);
|
||||
|
||||
/* Now get the number of hats */
|
||||
while (*joyenv == ' ' && *joyenv != 0) joyenv++; /* jump spaces... */
|
||||
joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber));
|
||||
joydata->hats = atoi(tempnumber);
|
||||
joydata->hats = SDL_atoi(tempnumber);
|
||||
|
||||
/* Now get the number of balls */
|
||||
while (*joyenv==' ' && *joyenv != 0) joyenv++; /* jump spaces... */
|
||||
joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber));
|
||||
joydata->balls = atoi(tempnumber);
|
||||
joydata->balls = SDL_atoi(tempnumber);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -742,7 +739,7 @@ static int joyGetEnv(struct _joycfg * joydata)
|
||||
/* Get a text from in the string starting in joyenv until it finds */
|
||||
/* the stopchar or maxchars is reached. The result is placed in name. */
|
||||
/************************************************************************/
|
||||
static int joyGetData(char *joyenv, char *name, char stopchar, size_t maxchars)
|
||||
static int joyGetData(const char *joyenv, char *name, char stopchar, size_t maxchars)
|
||||
{
|
||||
char *nameptr; /* Pointer to the selected character */
|
||||
int chcnt = 0; /* Count how many characters where copied */
|
||||
@@ -780,7 +777,7 @@ SDL_JoystickDriver SDL_OS2_JoystickDriver =
|
||||
OS2_JoystickOpen,
|
||||
OS2_JoystickRumble,
|
||||
OS2_JoystickRumbleTriggers,
|
||||
OS2_JoystickHasLED,
|
||||
OS2_JoystickGetCapabilities,
|
||||
OS2_JoystickSetLED,
|
||||
OS2_JoystickSendEffect,
|
||||
OS2_JoystickSetSensorsEnabled,
|
||||
|
@@ -209,9 +209,9 @@ PSP_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool PSP_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32 PSP_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -311,7 +311,7 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver =
|
||||
PSP_JoystickOpen,
|
||||
PSP_JoystickRumble,
|
||||
PSP_JoystickRumbleTriggers,
|
||||
PSP_JoystickHasLED,
|
||||
PSP_JoystickGetCapabilities,
|
||||
PSP_JoystickSetLED,
|
||||
PSP_JoystickSendEffect,
|
||||
PSP_JoystickSetSensorsEnabled,
|
||||
|
73
externals/SDL/src/joystick/usb_ids.h
vendored
73
externals/SDL/src/joystick/usb_ids.h
vendored
@@ -39,40 +39,45 @@
|
||||
#define USB_VENDOR_SONY 0x054c
|
||||
#define USB_VENDOR_VALVE 0x28de
|
||||
|
||||
#define USB_PRODUCT_AMAZON_LUNA_CONTROLLER 0x0419
|
||||
#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400
|
||||
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER 0x1846
|
||||
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
|
||||
#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009
|
||||
#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_RAZER_PANTHERA 0x0401
|
||||
#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008
|
||||
#define USB_PRODUCT_RAZER_ATROX 0x0a00
|
||||
#define USB_PRODUCT_SONY_DS4 0x05c4
|
||||
#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0
|
||||
#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc
|
||||
#define USB_PRODUCT_SONY_DS5 0x0ce6
|
||||
#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
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05
|
||||
#define USB_PRODUCT_XBOX_ONE_S 0x02ea
|
||||
#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0
|
||||
#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd
|
||||
#define USB_PRODUCT_XBOX_SERIES_X 0x0b12
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH 0x0b13
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002
|
||||
#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */
|
||||
#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */
|
||||
#define USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD 0x11ff
|
||||
#define USB_PRODUCT_AMAZON_LUNA_CONTROLLER 0x0419
|
||||
#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400
|
||||
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER 0x1846
|
||||
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
|
||||
#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009
|
||||
#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_RAZER_PANTHERA 0x0401
|
||||
#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008
|
||||
#define USB_PRODUCT_RAZER_ATROX 0x0a00
|
||||
#define USB_PRODUCT_SONY_DS4 0x05c4
|
||||
#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0
|
||||
#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc
|
||||
#define USB_PRODUCT_SONY_DS5 0x0ce6
|
||||
#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
|
||||
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE 0x0b0a
|
||||
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH 0x0b0c
|
||||
#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE 0x0b21
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE 0x0b22
|
||||
#define USB_PRODUCT_XBOX_ONE_S 0x02ea
|
||||
#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0
|
||||
#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd
|
||||
#define USB_PRODUCT_XBOX_ONE_S_REV2_BLE 0x0b20
|
||||
#define USB_PRODUCT_XBOX_SERIES_X 0x0b12
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_BLE 0x0b13
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002
|
||||
#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */
|
||||
#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */
|
||||
#define USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD 0x11ff
|
||||
|
||||
/* USB usage pages */
|
||||
#define USB_USAGEPAGE_GENERIC_DESKTOP 0x0001
|
||||
|
@@ -345,10 +345,10 @@ VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint1
|
||||
}
|
||||
|
||||
|
||||
static SDL_bool
|
||||
VIRTUAL_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
|
||||
VIRTUAL_JoystickOpen,
|
||||
VIRTUAL_JoystickRumble,
|
||||
VIRTUAL_JoystickRumbleTriggers,
|
||||
VIRTUAL_JoystickHasLED,
|
||||
VIRTUAL_JoystickGetCapabilities,
|
||||
VIRTUAL_JoystickSetLED,
|
||||
VIRTUAL_JoystickSendEffect,
|
||||
VIRTUAL_JoystickSetSensorsEnabled,
|
||||
|
@@ -365,11 +365,11 @@ VITA_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right)
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
VITA_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
VITA_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
// always return true for now
|
||||
return SDL_TRUE;
|
||||
// always return LED and rumble supported for now
|
||||
return SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver =
|
||||
VITA_JoystickRumble,
|
||||
VITA_JoystickRumbleTriggers,
|
||||
|
||||
VITA_JoystickHasLED,
|
||||
VITA_JoystickGetCapabilities,
|
||||
VITA_JoystickSetLED,
|
||||
VITA_JoystickSendEffect,
|
||||
VITA_JoystickSetSensorsEnabled,
|
||||
|
@@ -238,10 +238,21 @@ SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath)
|
||||
{
|
||||
SDL_GameControllerType type;
|
||||
|
||||
if (!SDL_XINPUT_Enabled()) {
|
||||
/* XInput and RawInput backends will pick up XInput-compatible devices */
|
||||
if (!SDL_XINPUT_Enabled()
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
&& !RAWINPUT_IsEnabled()
|
||||
#endif
|
||||
) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* If device path contains "IG_" then its an XInput device */
|
||||
/* See: https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput */
|
||||
if (SDL_strstr(hidPath, "IG_") != NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);
|
||||
if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
|
||||
type == SDL_CONTROLLER_TYPE_XBOXONE ||
|
||||
@@ -249,12 +260,6 @@ SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char* hidPath)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* If device path contains "IG_" then its an XInput device */
|
||||
/* See: https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput */
|
||||
if (SDL_strstr(hidPath, "IG_") != NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -427,7 +432,7 @@ SDL_DINPUT_JoystickInit(void)
|
||||
static BOOL CALLBACK
|
||||
EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
|
||||
{
|
||||
#define CHECK(exp) { if(!(exp)) goto err; }
|
||||
#define CHECK(expression) { if(!(expression)) goto err; }
|
||||
JoyStick_DeviceData *pNewJoystick = NULL;
|
||||
JoyStick_DeviceData *pPrevJoystick = NULL;
|
||||
Uint16 *guid16;
|
||||
@@ -548,11 +553,12 @@ typedef struct
|
||||
static BOOL CALLBACK
|
||||
EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
|
||||
{
|
||||
#define CHECK(exp) { if(!(exp)) goto err; }
|
||||
#define CHECK(expression) { if(!(expression)) goto err; }
|
||||
Joystick_PresentData *pData = (Joystick_PresentData *)pContext;
|
||||
Uint16 vendor = 0;
|
||||
Uint16 product = 0;
|
||||
LPDIRECTINPUTDEVICE8 device = NULL;
|
||||
BOOL result = DIENUM_CONTINUE;
|
||||
|
||||
/* We are only supporting HID devices. */
|
||||
CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0);
|
||||
@@ -562,7 +568,7 @@ EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext
|
||||
|
||||
if (vendor == pData->vendor && product == pData->product) {
|
||||
pData->present = SDL_TRUE;
|
||||
return DIENUM_STOP; /* get next device, please */
|
||||
result = DIENUM_STOP; /* found it */
|
||||
}
|
||||
|
||||
err:
|
||||
@@ -570,7 +576,7 @@ err:
|
||||
IDirectInputDevice8_Release(device);
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE; /* get next device, please */
|
||||
return result;
|
||||
#undef CHECK
|
||||
}
|
||||
|
||||
@@ -919,6 +925,18 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Uint8
|
||||
TranslatePOV(DWORD value)
|
||||
{
|
||||
@@ -1163,6 +1181,12 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@@ -25,6 +25,7 @@ extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
|
||||
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
|
||||
extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
|
||||
extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
extern Uint32 SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick);
|
||||
extern void SDL_DINPUT_JoystickQuit(void);
|
||||
|
@@ -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"
|
||||
@@ -47,7 +48,7 @@
|
||||
#ifdef HAVE_XINPUT_H
|
||||
#define SDL_JOYSTICK_RAWINPUT_XINPUT
|
||||
#endif
|
||||
#ifdef SDL_WINDOWS10_SDK
|
||||
#ifdef HAVE_WINDOWS_GAMING_INPUT_H
|
||||
#define SDL_JOYSTICK_RAWINPUT_WGI
|
||||
#endif
|
||||
|
||||
@@ -102,6 +103,7 @@ typedef struct _SDL_RAWINPUT_Device
|
||||
Uint16 version;
|
||||
SDL_JoystickGUID guid;
|
||||
SDL_bool is_xinput;
|
||||
SDL_bool is_xboxone;
|
||||
PHIDP_PREPARSED_DATA preparsed_data;
|
||||
|
||||
HANDLE hDevice;
|
||||
@@ -114,6 +116,7 @@ typedef struct _SDL_RAWINPUT_Device
|
||||
struct joystick_hwdata
|
||||
{
|
||||
SDL_bool is_xinput;
|
||||
SDL_bool is_xboxone;
|
||||
PHIDP_PREPARSED_DATA preparsed_data;
|
||||
ULONG max_data_length;
|
||||
HIDP_DATA *data;
|
||||
@@ -449,12 +452,12 @@ RAWINPUT_UpdateWindowsGamingInput()
|
||||
wgi_state.dirty = SDL_FALSE;
|
||||
|
||||
if (wgi_state.need_device_list_update) {
|
||||
HRESULT hr;
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads;
|
||||
wgi_state.need_device_list_update = SDL_FALSE;
|
||||
for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) {
|
||||
wgi_state.per_gamepad[ii]->connected = SDL_FALSE;
|
||||
}
|
||||
HRESULT hr;
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads;
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_get_Gamepads(wgi_state.gamepad_statics, &gamepads);
|
||||
if (SUCCEEDED(hr)) {
|
||||
@@ -479,13 +482,15 @@ RAWINPUT_UpdateWindowsGamingInput()
|
||||
}
|
||||
if (!found) {
|
||||
/* New device, add it */
|
||||
WindowsGamingInputGamepadState *gamepad_state;
|
||||
|
||||
wgi_state.per_gamepad_count++;
|
||||
wgi_state.per_gamepad = SDL_realloc(wgi_state.per_gamepad, sizeof(wgi_state.per_gamepad[0]) * wgi_state.per_gamepad_count);
|
||||
if (!wgi_state.per_gamepad) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
WindowsGamingInputGamepadState *gamepad_state = SDL_calloc(1, sizeof(*gamepad_state));
|
||||
gamepad_state = SDL_calloc(1, sizeof(*gamepad_state));
|
||||
if (!gamepad_state) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
@@ -531,6 +536,10 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||
wgi_state.need_device_list_update = SDL_TRUE;
|
||||
wgi_state.ref_count++;
|
||||
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;
|
||||
|
||||
/* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return;
|
||||
@@ -538,9 +547,7 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||
wgi_state.initialized = SDL_TRUE;
|
||||
wgi_state.dirty = SDL_TRUE;
|
||||
|
||||
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
||||
HRESULT hr;
|
||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||
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);
|
||||
@@ -554,7 +561,7 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
||||
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics);
|
||||
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
|
||||
}
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
@@ -672,7 +679,7 @@ RAWINPUT_DeviceFromHandle(HANDLE hDevice)
|
||||
static void
|
||||
RAWINPUT_AddDevice(HANDLE hDevice)
|
||||
{
|
||||
#define CHECK(exp) { if(!(exp)) goto err; }
|
||||
#define CHECK(expression) { if(!(expression)) goto err; }
|
||||
SDL_RAWINPUT_Device *device = NULL;
|
||||
SDL_RAWINPUT_Device *curr, *last;
|
||||
RID_DEVICE_INFO rdi;
|
||||
@@ -705,6 +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 = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController;
|
||||
|
||||
{
|
||||
const Uint16 vendor = device->vendor_id;
|
||||
@@ -1054,6 +1062,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
}
|
||||
|
||||
ctx->is_xinput = device->is_xinput;
|
||||
ctx->is_xboxone = device->is_xboxone;
|
||||
ctx->preparsed_data = device->preparsed_data;
|
||||
ctx->max_data_length = SDL_HidP_MaxDataListLength(HidP_Input, ctx->preparsed_data);
|
||||
ctx->data = (HIDP_DATA *)SDL_malloc(ctx->max_data_length * sizeof(*ctx->data));
|
||||
@@ -1268,7 +1277,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
|
||||
gamepad_state->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16;
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
return SDL_SetError("Setting vibration failed: 0x%x\n", hr);
|
||||
return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -1277,10 +1286,29 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
|
||||
#endif
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
RAWINPUT_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
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;
|
||||
|
||||
if (ctx->is_xboxone) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1520,7 +1548,7 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick)
|
||||
SDL_bool new_correlation_count = 0;
|
||||
if (RAWINPUT_MissingWindowsGamingInputSlot()) {
|
||||
Uint8 correlation_id;
|
||||
WindowsGamingInputGamepadState *slot_idx;
|
||||
WindowsGamingInputGamepadState *slot_idx = NULL;
|
||||
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
|
||||
@@ -1829,9 +1857,9 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT result = -1;
|
||||
|
||||
SDL_LockMutex(SDL_RAWINPUT_mutex);
|
||||
|
||||
if (SDL_RAWINPUT_inited) {
|
||||
SDL_LockMutex(SDL_RAWINPUT_mutex);
|
||||
|
||||
switch (msg) {
|
||||
case WM_INPUT_DEVICE_CHANGE:
|
||||
{
|
||||
@@ -1875,9 +1903,9 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockMutex(SDL_RAWINPUT_mutex);
|
||||
SDL_UnlockMutex(SDL_RAWINPUT_mutex);
|
||||
}
|
||||
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
@@ -1892,8 +1920,6 @@ RAWINPUT_JoystickQuit(void)
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(SDL_RAWINPUT_mutex);
|
||||
|
||||
while (SDL_RAWINPUT_devices) {
|
||||
RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE);
|
||||
}
|
||||
@@ -1904,7 +1930,6 @@ RAWINPUT_JoystickQuit(void)
|
||||
|
||||
SDL_RAWINPUT_inited = SDL_FALSE;
|
||||
|
||||
SDL_UnlockMutex(SDL_RAWINPUT_mutex);
|
||||
SDL_DestroyMutex(SDL_RAWINPUT_mutex);
|
||||
SDL_RAWINPUT_mutex = NULL;
|
||||
}
|
||||
@@ -1928,7 +1953,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
|
||||
RAWINPUT_JoystickOpen,
|
||||
RAWINPUT_JoystickRumble,
|
||||
RAWINPUT_JoystickRumbleTriggers,
|
||||
RAWINPUT_JoystickHasLED,
|
||||
RAWINPUT_JoystickGetCapabilities,
|
||||
RAWINPUT_JoystickSetLED,
|
||||
RAWINPUT_JoystickSendEffect,
|
||||
RAWINPUT_JoystickSetSensorsEnabled,
|
||||
|
@@ -31,6 +31,8 @@
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#define COBJMACROS
|
||||
#include "windows.gaming.input.h"
|
||||
#include <cfgmgr32.h>
|
||||
#include <roapi.h>
|
||||
|
||||
|
||||
struct joystick_hwdata
|
||||
@@ -77,15 +79,15 @@ static const IID IID_IGameController = { 0x1BAF6522, 0x5F64, 0x42C5, { 0x82, 0x6
|
||||
static const IID IID_IGameControllerBatteryInfo = { 0xDCECC681, 0x3963, 0x4DA6, { 0x95, 0x5D, 0x55, 0x3F, 0x3B, 0x6F, 0x61, 0x61 } };
|
||||
static const IID IID_IArcadeStickStatics = { 0x5C37B8C8, 0x37B1, 0x4AD8, { 0x94, 0x58, 0x20, 0x0F, 0x1A, 0x30, 0x01, 0x8E } };
|
||||
static const IID IID_IArcadeStickStatics2 = { 0x52B5D744, 0xBB86, 0x445A, { 0xB5, 0x9C, 0x59, 0x6F, 0x0E, 0x2A, 0x49, 0xDF } };
|
||||
static const IID IID_IArcadeStick = { 0xB14A539D, 0xBEFB, 0x4C81, { 0x80, 0x51, 0x15, 0xEC, 0xF3, 0xB1, 0x30, 0x36 } };
|
||||
/*static const IID IID_IArcadeStick = { 0xB14A539D, 0xBEFB, 0x4C81, { 0x80, 0x51, 0x15, 0xEC, 0xF3, 0xB1, 0x30, 0x36 } };*/
|
||||
static const IID IID_IFlightStickStatics = { 0x5514924A, 0xFECC, 0x435E, { 0x83, 0xDC, 0x5C, 0xEC, 0x8A, 0x18, 0xA5, 0x20 } };
|
||||
static const IID IID_IFlightStick = { 0xB4A2C01C, 0xB83B, 0x4459, { 0xA1, 0xA9, 0x97, 0xB0, 0x3C, 0x33, 0xDA, 0x7C } };
|
||||
/*static const IID IID_IFlightStick = { 0xB4A2C01C, 0xB83B, 0x4459, { 0xA1, 0xA9, 0x97, 0xB0, 0x3C, 0x33, 0xDA, 0x7C } };*/
|
||||
static const IID IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
||||
static const IID IID_IGamepadStatics2 = { 0x42676DC5, 0x0856, 0x47C4, { 0x92, 0x13, 0xB3, 0x95, 0x50, 0x4C, 0x3A, 0x3C } };
|
||||
static const IID IID_IGamepad = { 0xBC7BB43C, 0x0A69, 0x3903, { 0x9E, 0x9D, 0xA5, 0x0F, 0x86, 0xA4, 0x5D, 0xE5 } };
|
||||
/*static const IID IID_IGamepad = { 0xBC7BB43C, 0x0A69, 0x3903, { 0x9E, 0x9D, 0xA5, 0x0F, 0x86, 0xA4, 0x5D, 0xE5 } };*/
|
||||
static const IID IID_IRacingWheelStatics = { 0x3AC12CD5, 0x581B, 0x4936, { 0x9F, 0x94, 0x69, 0xF1, 0xE6, 0x51, 0x4C, 0x7D } };
|
||||
static const IID IID_IRacingWheelStatics2 = { 0xE666BCAA, 0xEDFD, 0x4323, { 0xA9, 0xF6, 0x3C, 0x38, 0x40, 0x48, 0xD1, 0xED } };
|
||||
static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } };
|
||||
/*static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } };*/
|
||||
|
||||
extern SDL_bool SDL_XINPUT_Enabled(void);
|
||||
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
|
||||
@@ -93,11 +95,17 @@ extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16
|
||||
static SDL_bool
|
||||
SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
||||
{
|
||||
#ifdef SDL_JOYSTICK_XINPUT
|
||||
PRAWINPUTDEVICELIST raw_devices = NULL;
|
||||
UINT i, raw_device_count = 0;
|
||||
LONG vidpid = MAKELONG(vendor, product);
|
||||
|
||||
if (!SDL_XINPUT_Enabled()) {
|
||||
/* XInput and RawInput backends will pick up XInput-compatible devices */
|
||||
if (!SDL_XINPUT_Enabled()
|
||||
#ifdef SDL_JOYSTICK_RAWINPUT
|
||||
&& !RAWINPUT_IsEnabled()
|
||||
#endif
|
||||
) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -123,17 +131,70 @@ SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
|
||||
char devName[MAX_PATH];
|
||||
UINT rdiSize = sizeof(rdi);
|
||||
UINT nameSize = SDL_arraysize(devName);
|
||||
DEVINST devNode;
|
||||
char devVidPidString[32];
|
||||
int j;
|
||||
|
||||
rdi.cbSize = sizeof(rdi);
|
||||
if ((raw_devices[i].dwType == RIM_TYPEHID) &&
|
||||
(GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
|
||||
(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) &&
|
||||
(GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
|
||||
(SDL_strstr(devName, "IG_") != NULL)) {
|
||||
|
||||
if ((raw_devices[i].dwType != RIM_TYPEHID) ||
|
||||
(GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1)) ||
|
||||
(GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) ||
|
||||
(SDL_strstr(devName, "IG_") == NULL)) {
|
||||
/* Skip non-XInput devices */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* First check for a simple VID/PID match. This will work for Xbox 360 controllers. */
|
||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) {
|
||||
SDL_free(raw_devices);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* For Xbox One controllers, Microsoft doesn't propagate the VID/PID down to the HID stack.
|
||||
* We'll have to walk the device tree upwards searching for a match for our VID/PID. */
|
||||
|
||||
/* Make sure the device interface string is something we know how to parse */
|
||||
/* Example: \\?\HID#VID_045E&PID_02FF&IG_00#9&2c203035&2&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */
|
||||
if ((SDL_strstr(devName, "\\\\?\\") != devName) || (SDL_strstr(devName, "#{") == NULL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Unescape the backslashes in the string and terminate before the GUID portion */
|
||||
for (j = 0; devName[j] != '\0'; j++) {
|
||||
if (devName[j] == '#') {
|
||||
if (devName[j + 1] == '{') {
|
||||
devName[j] = '\0';
|
||||
break;
|
||||
} else {
|
||||
devName[j] = '\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We'll be left with a string like this: \\?\HID\VID_045E&PID_02FF&IG_00\9&2c203035&2&0000
|
||||
* Simply skip the \\?\ prefix and we'll have a properly formed device instance ID */
|
||||
if (CM_Locate_DevNodeA(&devNode, &devName[4], CM_LOCATE_DEVNODE_NORMAL) != CR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_snprintf(devVidPidString, sizeof(devVidPidString), "VID_%04X&PID_%04X", vendor, product);
|
||||
|
||||
while (CM_Get_Parent(&devNode, devNode, 0) == CR_SUCCESS) {
|
||||
char deviceId[MAX_DEVICE_ID_LEN];
|
||||
|
||||
if ((CM_Get_Device_IDA(devNode, deviceId, SDL_arraysize(deviceId), 0) == CR_SUCCESS) &&
|
||||
(SDL_strstr(deviceId, devVidPidString) != NULL)) {
|
||||
/* The VID/PID matched a parent device */
|
||||
SDL_free(raw_devices);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(raw_devices);
|
||||
#endif /* SDL_JOYSTICK_XINPUT */
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -166,7 +227,13 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
||||
HRESULT hr;
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL;
|
||||
|
||||
hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller);
|
||||
/* We can get delayed calls to InvokeAdded() after WGI_JoystickQuit(). Do nothing if WGI is deinitialized.
|
||||
* FIXME: Can we tell if WGI has been quit and reinitialized prior to a delayed callback? */
|
||||
if (wgi.statics == NULL) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller);
|
||||
if (SUCCEEDED(hr)) {
|
||||
char *name = NULL;
|
||||
SDL_JoystickGUID guid;
|
||||
@@ -184,26 +251,37 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2);
|
||||
if (SUCCEEDED(hr)) {
|
||||
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
|
||||
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
||||
|
||||
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL;
|
||||
WindowsDeleteString_t WindowsDeleteStringFunc = NULL;
|
||||
#ifdef __WINRT__
|
||||
WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
|
||||
WindowsDeleteStringFunc = WindowsDeleteString;
|
||||
#else
|
||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
typedef PCWSTR (WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *length);
|
||||
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
||||
|
||||
WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
|
||||
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
||||
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
|
||||
HSTRING hString;
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL);
|
||||
if (string) {
|
||||
name = WIN_StringToUTF8W(string);
|
||||
}
|
||||
WindowsDeleteStringFunc(hString);
|
||||
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
|
||||
WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
||||
}
|
||||
#endif /* __WINRT__ */
|
||||
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
|
||||
HSTRING hString;
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL);
|
||||
if (string) {
|
||||
name = WIN_StringToUTF8W(string);
|
||||
}
|
||||
WindowsDeleteStringFunc(hString);
|
||||
}
|
||||
}
|
||||
#ifndef __WINRT__
|
||||
if (hModule != NULL) {
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
#endif
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
|
||||
}
|
||||
if (!name) {
|
||||
@@ -310,7 +388,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeRemo
|
||||
HRESULT hr;
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL;
|
||||
|
||||
hr = IUnknown_QueryInterface((IUnknown *)e, &IID_IRawGameController, (void **)&controller);
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller);
|
||||
if (SUCCEEDED(hr)) {
|
||||
int i;
|
||||
|
||||
@@ -361,87 +439,120 @@ static __FIEventHandler_1_Windows__CGaming__CInput__CRawGameController controlle
|
||||
static int
|
||||
WGI_JoystickInit(void)
|
||||
{
|
||||
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);
|
||||
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
|
||||
#ifndef __WINRT__
|
||||
HMODULE hModule;
|
||||
#endif
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return SDL_SetError("CoInitialize() failed");
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||
#ifdef __WINRT__
|
||||
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
|
||||
RoGetActivationFactoryFunc = RoGetActivationFactory;
|
||||
#else
|
||||
hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
|
||||
typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string);
|
||||
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
|
||||
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
||||
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||
}
|
||||
#endif /* __WINRT__ */
|
||||
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
||||
PCWSTR pNamespace;
|
||||
HSTRING_HEADER hNamespaceStringHeader;
|
||||
HSTRING hNamespaceString;
|
||||
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
||||
PCWSTR pNamespace;
|
||||
HSTRING_HEADER hNamespaceStringHeader;
|
||||
HSTRING hNamespaceString;
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.RawGameController";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, &wgi.statics);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%x", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, &wgi.arcade_stick_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, &wgi.arcade_stick_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%x", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.FlightStick";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, &wgi.flight_stick_statics);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%x", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.Gamepad";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, &wgi.gamepad_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, &wgi.gamepad_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IGamepadStatics: 0x%x", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.RacingWheel";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, &wgi.racing_wheel_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, &wgi.racing_wheel_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%x", hr);
|
||||
}
|
||||
pNamespace = L"Windows.Gaming.Input.RawGameController";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.FlightStick";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.Gamepad";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr);
|
||||
}
|
||||
}
|
||||
|
||||
pNamespace = L"Windows.Gaming.Input.RacingWheel";
|
||||
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics);
|
||||
if (SUCCEEDED(hr)) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2);
|
||||
} else {
|
||||
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef __WINRT__
|
||||
if (hModule != NULL) {
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wgi.statics) {
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers;
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerAdded(wgi.statics, &controller_added, &wgi.controller_added_token);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("add_RawGameControllerAdded() failed: 0x%x\n", hr);
|
||||
SDL_SetError("add_RawGameControllerAdded() failed: 0x%lx\n", hr);
|
||||
}
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerRemoved(wgi.statics, &controller_removed, &wgi.controller_removed_token);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
SDL_SetError("add_RawGameControllerRemoved() failed: 0x%x\n", hr);
|
||||
SDL_SetError("add_RawGameControllerRemoved() failed: 0x%lx\n", hr);
|
||||
}
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_get_RawGameControllers(wgi.statics, &controllers);
|
||||
if (SUCCEEDED(hr)) {
|
||||
unsigned i, count = 0;
|
||||
|
||||
hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_get_Size(controllers, &count);
|
||||
if (SUCCEEDED(hr)) {
|
||||
for (i = 0; i < count; ++i) {
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL;
|
||||
|
||||
hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_GetAt(controllers, i, &controller);
|
||||
if (SUCCEEDED(hr) && controller) {
|
||||
IEventHandler_CRawGameControllerVtbl_InvokeAdded(&controller_added, NULL, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,7 +685,7 @@ WGI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
|
||||
if (SUCCEEDED(hr)) {
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("Setting vibration failed: 0x%x\n", hr);
|
||||
return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
|
||||
}
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
@@ -595,17 +706,24 @@ WGI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
||||
if (SUCCEEDED(hr)) {
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("Setting vibration failed: 0x%x\n", hr);
|
||||
return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
|
||||
}
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WGI_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
WGI_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
struct joystick_hwdata *hwdata = joystick->hwdata;
|
||||
|
||||
if (hwdata->gamepad) {
|
||||
/* FIXME: Can WGI even tell us if trigger rumble is supported? */
|
||||
return SDL_JOYCAP_RUMBLE | SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -713,7 +831,7 @@ WGI_JoystickQuit(void)
|
||||
{
|
||||
if (wgi.statics) {
|
||||
while (wgi.controller_count > 0) {
|
||||
IEventHandler_CRawGameControllerVtbl_InvokeRemoved(&controller_removed, NULL, (__x_ABI_CWindows_CGaming_CInput_CIRawGameController *)wgi.controllers[wgi.controller_count - 1].controller);
|
||||
IEventHandler_CRawGameControllerVtbl_InvokeRemoved(&controller_removed, NULL, wgi.controllers[wgi.controller_count - 1].controller);
|
||||
}
|
||||
if (wgi.controllers) {
|
||||
SDL_free(wgi.controllers);
|
||||
@@ -813,7 +931,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver =
|
||||
WGI_JoystickOpen,
|
||||
WGI_JoystickRumble,
|
||||
WGI_JoystickRumbleTriggers,
|
||||
WGI_JoystickHasLED,
|
||||
WGI_JoystickGetCapabilities,
|
||||
WGI_JoystickSetLED,
|
||||
WGI_JoystickSendEffect,
|
||||
WGI_JoystickSetSensorsEnabled,
|
||||
|
@@ -151,7 +151,7 @@ static DWORD CALLBACK
|
||||
SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size)
|
||||
{
|
||||
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
|
||||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
|
||||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
@@ -179,15 +179,15 @@ SDL_CreateDeviceNotificationFunc(void)
|
||||
CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification");
|
||||
CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification");
|
||||
if (CM_Register_Notification && CM_Unregister_Notification) {
|
||||
CM_NOTIFY_FILTER notify_filter;
|
||||
CM_NOTIFY_FILTER notify_filter;
|
||||
|
||||
SDL_zero(notify_filter);
|
||||
notify_filter.cbSize = sizeof(notify_filter);
|
||||
notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
|
||||
notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID;
|
||||
if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
|
||||
notify_filter.cbSize = sizeof(notify_filter);
|
||||
notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
|
||||
notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID;
|
||||
if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,10 +658,14 @@ WINDOWS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint1
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WINDOWS_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
WINDOWS_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
if (joystick->hwdata->bXInputDevice) {
|
||||
return SDL_XINPUT_JoystickGetCapabilities(joystick);
|
||||
} else {
|
||||
return SDL_DINPUT_JoystickGetCapabilities(joystick);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -758,7 +762,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickOpen,
|
||||
WINDOWS_JoystickRumble,
|
||||
WINDOWS_JoystickRumbleTriggers,
|
||||
WINDOWS_JoystickHasLED,
|
||||
WINDOWS_JoystickGetCapabilities,
|
||||
WINDOWS_JoystickSetLED,
|
||||
WINDOWS_JoystickSendEffect,
|
||||
WINDOWS_JoystickSetSensorsEnabled,
|
||||
|
@@ -503,6 +503,12 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
@@ -579,6 +585,12 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
Uint32
|
||||
SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
|
@@ -27,6 +27,7 @@ extern int SDL_XINPUT_JoystickInit(void);
|
||||
extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext);
|
||||
extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice);
|
||||
extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
extern Uint32 SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick);
|
||||
extern void SDL_XINPUT_JoystickQuit(void);
|
||||
|
Reference in New Issue
Block a user