Update SDL3 from 3.2.4 to 3.2.20

This commit is contained in:
Sven Balzer
2025-08-27 21:24:05 +02:00
parent 6283160467
commit ad651462df
332 changed files with 20334 additions and 4852 deletions
+50 -36
View File
@@ -311,7 +311,7 @@ void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
{
SDL_Event event;
if (!SDL_gamepads_initialized) {
if (!SDL_gamepads_initialized || SDL_IsJoystickBeingAdded()) {
return;
}
@@ -405,15 +405,17 @@ static bool SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
{
SDL_AssertJoysticksLocked();
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
if (gamepad->joystick->instance_id == event->jdevice.which) {
SDL_Event deviceevent;
if (SDL_EventEnabled(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE)) {
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
if (gamepad->joystick->instance_id == event->jdevice.which) {
SDL_Event deviceevent;
deviceevent.type = SDL_EVENT_GAMEPAD_UPDATE_COMPLETE;
deviceevent.common.timestamp = event->jdevice.timestamp;
deviceevent.gdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
break;
deviceevent.type = SDL_EVENT_GAMEPAD_UPDATE_COMPLETE;
deviceevent.common.timestamp = event->jdevice.timestamp;
deviceevent.gdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
break;
}
}
}
} break;
@@ -428,7 +430,7 @@ static bool SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
orientation, so when it's changed orientation to be used as a
gamepad, change the sensor orientation to match.
*/
static void AdjustSensorOrientation(SDL_Joystick *joystick, float *src, float *dst)
static void AdjustSensorOrientation(const SDL_Joystick *joystick, const float *src, float *dst)
{
unsigned int i, j;
@@ -562,12 +564,10 @@ static void PopMappingChangeTracking(void)
GamepadMapping_t *old_mapping = gamepad ? gamepad->mapping : tracker->joystick_mappings[i];
if (new_mapping && !old_mapping) {
SDL_RemoveFromHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)true);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)true, true);
SDL_PrivateGamepadAdded(joystick);
} else if (old_mapping && !new_mapping) {
SDL_RemoveFromHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)false);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)false, true);
SDL_PrivateGamepadRemoved(joystick);
} else if (old_mapping != new_mapping || HasMappingChangeTracking(tracker, new_mapping)) {
if (gamepad) {
@@ -731,7 +731,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string));
break;
case k_eSwitchDeviceInfoControllerType_SNES:
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string));
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
break;
case k_eSwitchDeviceInfoControllerType_N64:
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b11,", sizeof(mapping_string));
@@ -775,13 +775,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
// All other gamepads have the standard set of 19 buttons and 6 axes
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string));
if (SDL_IsJoystickXboxSeriesX(vendor, product)) {
// XBox Series X Controllers have a share button under the guide button
SDL_strlcat(mapping_string, "misc1:b11,", sizeof(mapping_string));
} else if (SDL_IsJoystickXboxOneElite(vendor, product)) {
// XBox One Elite Controllers have 4 back paddle buttons
SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,", sizeof(mapping_string));
} else if (SDL_IsJoystickSteamController(vendor, product)) {
if (SDL_IsJoystickSteamController(vendor, product)) {
// Steam controllers have 2 back paddle buttons
SDL_strlcat(mapping_string, "paddle1:b12,paddle2:b11,", sizeof(mapping_string));
} else if (SDL_IsJoystickNintendoSwitchPro(vendor, product) ||
@@ -822,6 +816,15 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
SDL_strlcat(mapping_string, "paddle1:b16,paddle2:b15,paddle3:b14,paddle4:b13,", sizeof(mapping_string));
}
break;
case SDL_GAMEPAD_TYPE_XBOXONE:
if (SDL_IsJoystickXboxOneElite(vendor, product)) {
// XBox One Elite Controllers have 4 back paddle buttons
SDL_strlcat(mapping_string, "paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,", sizeof(mapping_string));
} else if (SDL_IsJoystickXboxSeriesX(vendor, product)) {
// XBox Series X Controllers have a share button under the guide button
SDL_strlcat(mapping_string, "misc1:b11,", sizeof(mapping_string));
}
break;
default:
if (vendor == 0 && product == 0) {
// This is a Bluetooth Nintendo Switch Pro controller
@@ -910,7 +913,7 @@ static GamepadMapping_t *SDL_PrivateMatchGamepadMappingForGUID(SDL_GUID guid, bo
// An exact match, including CRC
return mapping;
} else if (crc && exact_match_crc) {
return NULL;
continue;
}
if (!best_match) {
@@ -1396,17 +1399,22 @@ static void SDL_UpdateGamepadFaceStyle(SDL_Gamepad *gamepad)
static void SDL_FixupHIDAPIMapping(SDL_Gamepad *gamepad)
{
// Check to see if we need fixup
bool need_fixup = false;
for (int i = 0; i < gamepad->num_bindings; ++i) {
SDL_GamepadBinding *binding = &gamepad->bindings[i];
if (binding->output_type == SDL_GAMEPAD_BINDTYPE_BUTTON &&
binding->output.button == SDL_GAMEPAD_BUTTON_DPAD_UP) {
if (binding->input_type != SDL_GAMEPAD_BINDTYPE_BUTTON ||
binding->input.button != SDL_GAMEPAD_BUTTON_DPAD_UP) {
// New style binding
return;
binding->output.button >= SDL_GAMEPAD_BUTTON_DPAD_UP) {
if (binding->input_type == SDL_GAMEPAD_BINDTYPE_BUTTON &&
binding->input.button == binding->output.button) {
// Old style binding
need_fixup = true;
}
break;
}
}
if (!need_fixup) {
return;
}
for (int i = 0; i < gamepad->num_bindings; ++i) {
SDL_GamepadBinding *binding = &gamepad->bindings[i];
@@ -1778,6 +1786,11 @@ static GamepadMapping_t *SDL_PrivateGenerateAutomaticGamepadMapping(const char *
char name_string[128];
char mapping[1024];
// Remove the CRC from the GUID
// We already know that this GUID doesn't have a mapping without the CRC, and we want newly
// added mappings without a CRC to override this mapping.
SDL_SetJoystickGUIDCRC(&guid, 0);
// Remove any commas in the name
SDL_strlcpy(name_string, name, sizeof(name_string));
{
@@ -2637,9 +2650,9 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id)
}
if (!s_gamepadInstanceIDs) {
s_gamepadInstanceIDs = SDL_CreateHashTable(NULL, 4, SDL_HashID, SDL_KeyMatchID, NULL, false, false);
s_gamepadInstanceIDs = SDL_CreateHashTable(0, false, SDL_HashID, SDL_KeyMatchID, NULL, NULL);
}
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, (void *)(uintptr_t)result);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, (void *)(uintptr_t)result, true);
}
}
SDL_UnlockJoysticks();
@@ -2746,6 +2759,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id)
gamepad->joystick = SDL_OpenJoystick(instance_id);
if (!gamepad->joystick) {
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false);
SDL_free(gamepad);
SDL_UnlockJoysticks();
return NULL;
@@ -2754,6 +2768,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id)
if (gamepad->joystick->naxes) {
gamepad->last_match_axis = (SDL_GamepadBinding **)SDL_calloc(gamepad->joystick->naxes, sizeof(*gamepad->last_match_axis));
if (!gamepad->last_match_axis) {
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false);
SDL_CloseJoystick(gamepad->joystick);
SDL_free(gamepad);
SDL_UnlockJoysticks();
@@ -2763,6 +2778,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id)
if (gamepad->joystick->nhats) {
gamepad->last_hat_mask = (Uint8 *)SDL_calloc(gamepad->joystick->nhats, sizeof(*gamepad->last_hat_mask));
if (!gamepad->last_hat_mask) {
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, false);
SDL_CloseJoystick(gamepad->joystick);
SDL_free(gamepad->last_match_axis);
SDL_free(gamepad);
@@ -2824,7 +2840,7 @@ bool SDL_GamepadHasAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis)
*/
Sint16 SDL_GetGamepadAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis)
{
Sint16 result = true;
Sint16 result = 0;
SDL_LockJoysticks();
{
@@ -3054,7 +3070,7 @@ SDL_GamepadButtonLabel SDL_GetGamepadButtonLabel(SDL_Gamepad *gamepad, SDL_Gamep
*/
int SDL_GetNumGamepadTouchpads(SDL_Gamepad *gamepad)
{
int result = true;
int result = 0;
SDL_LockJoysticks();
{
@@ -3073,7 +3089,7 @@ int SDL_GetNumGamepadTouchpads(SDL_Gamepad *gamepad)
*/
int SDL_GetNumGamepadTouchpadFingers(SDL_Gamepad *gamepad, int touchpad)
{
int result = true;
int result = 0;
SDL_LockJoysticks();
{
@@ -3081,8 +3097,6 @@ int SDL_GetNumGamepadTouchpadFingers(SDL_Gamepad *gamepad, int touchpad)
if (joystick) {
if (touchpad >= 0 && touchpad < joystick->ntouchpads) {
result = joystick->touchpads[touchpad].nfingers;
} else {
result = SDL_InvalidParamError("touchpad");
}
}
}
@@ -3326,7 +3340,7 @@ SDL_JoystickID SDL_GetGamepadID(SDL_Gamepad *gamepad)
SDL_PropertiesID SDL_GetGamepadProperties(SDL_Gamepad *gamepad)
{
SDL_PropertiesID result = true;
SDL_PropertiesID result = 0;
SDL_LockJoysticks();
{
+20 -2
View File
@@ -50,6 +50,7 @@ static const char *s_GamepadMappings[] = {
"03000000c82d00001038000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000650000000000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,",
"03000000c82d00005106000000000000,8BitDo M30 Gamepad,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,",
"03000000c82d00002090000000000000,8BitDo Micro gamepad,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b12,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000003512000012ab000000000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -214,6 +215,7 @@ static const char *s_GamepadMappings[] = {
"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,",
"03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,",
"030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,",
"0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,",
"030000006f0e00000901000000000000,PDP Versus Fighting Pad,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,",
"03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
@@ -299,7 +301,6 @@ static const char *s_GamepadMappings[] = {
"03000000a30600002106000000000000,Saitek PS1000,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:a4,start:b9,x:b0,y:b3,",
"03000000a306000020f6000000000000,Saitek PS2700,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:a4,start:b9,x:b0,y:b3,",
"03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,",
"03000000790000000600000000000000,Sanwa Supply JY-P76USV,crc:20f0,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,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b2,y:b3,",
"0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,",
"030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,",
"030000008f0e00000800000000000000,SpeedLink Strike FX,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,",
@@ -350,6 +351,7 @@ static const char *s_GamepadMappings[] = {
"03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000650000001000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000ac05000004000000a8986d04,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -414,11 +416,13 @@ static const char *s_GamepadMappings[] = {
"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,",
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,",
"03000000853200008906000000010000,NACON Revolution X Unlimited,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,",
"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,",
"03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
"030000004b120000014d000000010000,NYKO AIRFLO EX,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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,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:b2,y:b3,",
"050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
"030000006f0e00000901000002010000,PDP Versus Fighting Pad,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,",
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
@@ -486,6 +490,7 @@ static const char *s_GamepadMappings[] = {
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d00002090000000010000,8BitDo Micro gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b12,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000003512000012ab000010010000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -549,6 +554,7 @@ static const char *s_GamepadMappings[] = {
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
"03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
"0500000049190000020400001b010000,GameSir T4 Pro,crc:8283,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b23,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,",
"03000000373500009710000001020000,GameSir-K1 FLUX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"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,",
"03000000c01100000140000011010000,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,",
@@ -637,6 +643,12 @@ static const char *s_GamepadMappings[] = {
"030000004b120000014d000000010000,NYKO AIRFLO EX,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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
"03000000451300000830000010010000,NYKO CORE,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:a5,start:b9,x:b0,y:b3,",
"03000000790000004318000010010000,Nintendo GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"030000007e0500001920000011810000,Nintendo N64 Controller,crc:d670,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b3,start:b11,x:b4,y:b10,",
"050000007e0500001920000001800000,Nintendo N64 Controller,crc:5e1c,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b5,rightshoulder:b7,righttrigger:b3,start:b11,x:b4,y:b10,",
"030000007e0500001e20000011810000,Nintendo SEGA Genesis Controller,crc:bb22,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,misc1:b3,rightshoulder:b2,righttrigger:b4,start:b5,",
"050000007e0500001720000001800000,Nintendo SEGA Genesis Controller,crc:c1bf,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,misc1:b3,rightshoulder:b2,righttrigger:b4,start:b5,",
"030000007e0500001720000011810000,Nintendo SNES Controller,crc:f648,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"050000007e0500001720000001800000,Nintendo SNES Controller,crc:dbc0,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"050000007e0500000620000001800000,Nintendo Switch Joy-Con (L),a:b16,b:b15,guide:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"060000007e0500000620000000000000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"060000007e0500000820000000000000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -785,6 +797,7 @@ static const char *s_GamepadMappings[] = {
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,crc:82d5,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000120c0000182e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -800,6 +813,7 @@ static const char *s_GamepadMappings[] = {
#ifdef SDL_PLATFORM_ANDROID
"05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000020900000ffff3f00,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b5,leftshoulder:b9,lefttrigger:a6,rightshoulder:b10,righttrigger:a7,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -855,6 +869,10 @@ static const char *s_GamepadMappings[] = {
"05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
"05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,",
"05000000ac05000004000000a8986d04,8BitDo Micro gamepad,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,lefttrigger:b12,rightshoulder:b13,righttrigger:b14,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000ac05000004000000fd216d04,8BitDo Pro 2,crc:ac95,a:b3,b:b2,back:b6,dpdown:b9,dpleft:b10,dpright:b11,dpup:b12,guide:b4,leftshoulder:b13,leftstick:b14,lefttrigger:+a2,leftx:a0,lefty:a1~,paddle1:b1,paddle2:b0,rightshoulder:b16,rightstick:b17,righttrigger:+a5,rightx:a3,righty:a4~,start:b5,x:b8,y:b7,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000ac050000040000003b8a6d04,8BitDo SN30 Pro+,crc:3e00,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000ac05000004000000209f6d04,8Bitdo SN30 Pro,crc:40d6,a:b1,b:b0,back:b4,dpdown:b7,dpleft:b8,dpright:b9,dpup:b10,guide:b2,leftshoulder:b11,leftstick:b12,lefttrigger:b13,leftx:a0,lefty:a1~,rightshoulder:b14,rightstick:b15,righttrigger:b16,rightx:a2,righty:a3~,start:b3,x:b6,y:b5,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"050000008a35000003010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000008a35000004010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000007e050000062000000f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -891,7 +909,7 @@ static const char *s_GamepadMappings[] = {
"0000000050535669746120436f6e7400,PSVita Controller,crc:d598,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
#endif
#ifdef SDL_JOYSTICK_N3DS
"000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b0,b:b1,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b10,y:b11,",
"000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b1,b:b0,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b11,y:b10,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
#endif
NULL
};
+136 -150
View File
@@ -277,6 +277,7 @@ static Uint32 initial_blacklist_devices[] = {
MAKE_VIDPID(0x1532, 0x0282), // Razer Huntsman Mini Analog, non-functional DInput device
MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller
MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only)
MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control
};
static SDL_vidpid_list blacklist_devices = {
SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL,
@@ -289,7 +290,17 @@ static Uint32 initial_flightstick_devices[] = {
MAKE_VIDPID(0x044f, 0x0402), // HOTAS Warthog Joystick
MAKE_VIDPID(0x044f, 0xb10a), // ThrustMaster, Inc. T.16000M Joystick
MAKE_VIDPID(0x046d, 0xc215), // Logitech Extreme 3D
MAKE_VIDPID(0x0583, 0x6258), // Padix USB joystick with viewfinder
MAKE_VIDPID(0x0583, 0x688f), // Padix QF-688uv Windstorm Pro
MAKE_VIDPID(0x0583, 0x7070), // Padix QF-707u Bazooka
MAKE_VIDPID(0x0583, 0xa019), // Padix USB vibration joystick with viewfinder
MAKE_VIDPID(0x0583, 0xa131), // Padix USB Wireless 2.4GHz
MAKE_VIDPID(0x0583, 0xa209), // Padix MetalStrike ForceFeedback
MAKE_VIDPID(0x0583, 0xb010), // Padix MetalStrike Pro
MAKE_VIDPID(0x0583, 0xb012), // Padix Wireless MetalStrike
MAKE_VIDPID(0x0583, 0xb013), // Padix USB Wireless 2.4GHZ
MAKE_VIDPID(0x0738, 0x2221), // Saitek Pro Flight X-56 Rhino Stick
MAKE_VIDPID(0x10f5, 0x7084), // Turtle Beach VelocityOne
MAKE_VIDPID(0x231d, 0x0126), // Gunfighter Mk.III 'Space Combat Edition' (right)
MAKE_VIDPID(0x231d, 0x0127), // Gunfighter Mk.III 'Space Combat Edition' (left)
MAKE_VIDPID(0x362c, 0x0001), // Yawman Arrow
@@ -331,6 +342,7 @@ static SDL_vidpid_list rog_gamepad_mice = {
static Uint32 initial_throttle_devices[] = {
MAKE_VIDPID(0x044f, 0x0404), // HOTAS Warthog Throttle
MAKE_VIDPID(0x0738, 0xa221), // Saitek Pro Flight X-56 Rhino Throttle
MAKE_VIDPID(0x10f5, 0x7085), // Turtle Beach VelocityOne Throttle
};
static SDL_vidpid_list throttle_devices = {
SDL_HINT_JOYSTICK_THROTTLE_DEVICES, 0, 0, NULL,
@@ -374,6 +386,14 @@ static Uint32 initial_wheel_devices[] = {
MAKE_VIDPID(0x046d, 0xca03), // Logitech Momo Racing
MAKE_VIDPID(0x0483, 0x0522), // Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U)
MAKE_VIDPID(0x0483, 0xa355), // VRS DirectForce Pro Wheel Base
MAKE_VIDPID(0x0583, 0xa132), // Padix USB Wireless 2.4GHz Wheelpad
MAKE_VIDPID(0x0583, 0xa133), // Padix USB Wireless 2.4GHz Wheel
MAKE_VIDPID(0x0583, 0xa202), // Padix Force Feedback Wheel
MAKE_VIDPID(0x0583, 0xb002), // Padix Vibration USB Wheel
MAKE_VIDPID(0x0583, 0xb005), // Padix USB Wheel
MAKE_VIDPID(0x0583, 0xb008), // Padix USB Wireless 2.4GHz Wheel
MAKE_VIDPID(0x0583, 0xb009), // Padix USB Wheel
MAKE_VIDPID(0x0583, 0xb018), // Padix TW6 Wheel
MAKE_VIDPID(0x0eb7, 0x0001), // Fanatec ClubSport Wheel Base V2
MAKE_VIDPID(0x0eb7, 0x0004), // Fanatec ClubSport Wheel Base V2.5
MAKE_VIDPID(0x0eb7, 0x0005), // Fanatec CSL Elite Wheel Base+ (PS4)
@@ -427,6 +447,13 @@ static SDL_vidpid_list zero_centered_devices = {
return result; \
}
#define CHECK_JOYSTICK_VIRTUAL(joystick, result) \
if (!joystick->is_virtual) { \
SDL_SetError("joystick isn't virtual"); \
SDL_UnlockJoysticks(); \
return result; \
}
bool SDL_JoysticksInitialized(void)
{
return SDL_joysticks_initialized;
@@ -1043,6 +1070,27 @@ static void CleanupSensorFusion(SDL_Joystick *joystick)
}
}
static bool ShouldSwapFaceButtons(const SDL_SteamVirtualGamepadInfo *info)
{
// When "Use Nintendo Button Layout" is enabled under Steam (the default)
// it will send button 0 for the A (east) button and button 1 for the
// B (south) button. This is done so that games that interpret the
// buttons as Xbox input will get button 0 for "A" as they expect.
//
// However, SDL reports positional buttons, so we need to swap
// the buttons so they show up in the correct position. This provides
// consistent behavior regardless of whether we're running under Steam,
// under the default settings.
if (info &&
(info->type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO ||
info->type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT ||
info->type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT ||
info->type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR)) {
return true;
}
return false;
}
/*
* Open a joystick for use - the index passed as an argument refers to
* the N'th joystick on the system. This index is the value which will
@@ -1094,6 +1142,11 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
joystick->attached = true;
joystick->led_expiration = SDL_GetTicks();
joystick->battery_percent = -1;
#ifdef SDL_JOYSTICK_VIRTUAL
joystick->is_virtual = (driver == &SDL_VIRTUAL_JoystickDriver);
#else
joystick->is_virtual = false;
#endif
if (!driver->Open(joystick, device_index)) {
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, false);
@@ -1137,9 +1190,35 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
// If this joystick is known to have all zero centered axes, skip the auto-centering code
if (SDL_JoystickAxesCenteredAtZero(joystick)) {
int i;
for (int i = 0; i < joystick->naxes; ++i) {
joystick->axes[i].has_initial_value = true;
}
}
for (i = 0; i < joystick->naxes; ++i) {
// We know the initial values for HIDAPI and XInput joysticks
if ((SDL_IsJoystickHIDAPI(joystick->guid) ||
SDL_IsJoystickXInput(joystick->guid) ||
SDL_IsJoystickRAWINPUT(joystick->guid) ||
SDL_IsJoystickWGI(joystick->guid)) &&
joystick->naxes >= SDL_GAMEPAD_AXIS_COUNT) {
int left_trigger, right_trigger;
if (SDL_IsJoystickXInput(joystick->guid)) {
left_trigger = 2;
right_trigger = 5;
} else {
left_trigger = SDL_GAMEPAD_AXIS_LEFT_TRIGGER;
right_trigger = SDL_GAMEPAD_AXIS_RIGHT_TRIGGER;
}
for (int i = 0; i < SDL_GAMEPAD_AXIS_COUNT; ++i) {
int initial_value;
if (i == left_trigger || i == right_trigger) {
initial_value = SDL_MIN_SINT16;
} else {
initial_value = 0;
}
joystick->axes[i].value = initial_value;
joystick->axes[i].zero = initial_value;
joystick->axes[i].initial_value = initial_value;
joystick->axes[i].has_initial_value = true;
}
}
@@ -1148,6 +1227,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
info = SDL_GetJoystickVirtualGamepadInfoForID(instance_id);
if (info) {
joystick->steam_handle = info->handle;
joystick->swap_face_buttons = ShouldSwapFaceButtons(info);
}
// Use system gyro and accelerometer if the gamepad doesn't have built-in sensors
@@ -1225,6 +1305,7 @@ bool SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value)
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SetJoystickVirtualAxisInner(joystick, axis, value);
@@ -1244,6 +1325,7 @@ bool SDL_SetJoystickVirtualBall(SDL_Joystick *joystick, int ball, Sint16 xrel, S
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SetJoystickVirtualBallInner(joystick, ball, xrel, yrel);
@@ -1263,6 +1345,7 @@ bool SDL_SetJoystickVirtualButton(SDL_Joystick *joystick, int button, bool down)
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SetJoystickVirtualButtonInner(joystick, button, down);
@@ -1282,6 +1365,7 @@ bool SDL_SetJoystickVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value)
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SetJoystickVirtualHatInner(joystick, hat, value);
@@ -1301,6 +1385,7 @@ bool SDL_SetJoystickVirtualTouchpad(SDL_Joystick *joystick, int touchpad, int fi
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SetJoystickVirtualTouchpadInner(joystick, touchpad, finger, down, x, y, pressure);
@@ -1320,6 +1405,7 @@ bool SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType ty
SDL_LockJoysticks();
{
CHECK_JOYSTICK_MAGIC(joystick, false);
CHECK_JOYSTICK_VIRTUAL(joystick, false);
#ifdef SDL_JOYSTICK_VIRTUAL
result = SDL_SendJoystickVirtualSensorDataInner(joystick, type, sensor_timestamp, data, num_values);
@@ -1778,6 +1864,14 @@ bool SDL_RumbleJoystickTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
result = true;
} else {
result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
if (result) {
joystick->trigger_rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS;
if (joystick->trigger_rumble_resend == 0) {
joystick->trigger_rumble_resend = 1;
}
} else {
joystick->trigger_rumble_resend = 0;
}
}
if (result) {
@@ -1788,6 +1882,7 @@ bool SDL_RumbleJoystickTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
} else {
joystick->trigger_rumble_expiration = 0;
joystick->trigger_rumble_resend = 0;
}
}
}
@@ -2048,6 +2143,7 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
SDL_JoystickDriver *driver;
int device_index;
int player_index = -1;
bool is_gamepad;
SDL_AssertJoysticksLocked();
@@ -2082,9 +2178,12 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
}
}
// This might create an automatic gamepad mapping, so wait to send the event
is_gamepad = SDL_IsGamepad(instance_id);
SDL_joystick_being_added = false;
if (SDL_IsGamepad(instance_id)) {
if (is_gamepad) {
SDL_PrivateGamepadAdded(instance_id);
}
}
@@ -2305,6 +2404,25 @@ void SDL_SendJoystickButton(Uint64 timestamp, SDL_Joystick *joystick, Uint8 butt
event.type = SDL_EVENT_JOYSTICK_BUTTON_UP;
}
if (joystick->swap_face_buttons) {
switch (button) {
case 0:
button = 1;
break;
case 1:
button = 0;
break;
case 2:
button = 3;
break;
case 3:
button = 2;
break;
default:
break;
}
}
// Make sure we're not getting garbage or duplicate events
if (button >= joystick->nbuttons) {
return;
@@ -2353,11 +2471,13 @@ static void SendSteamHandleUpdateEvents(void)
if (info) {
if (joystick->steam_handle != info->handle) {
joystick->steam_handle = info->handle;
joystick->swap_face_buttons = ShouldSwapFaceButtons(info);
changed = true;
}
} else {
if (joystick->steam_handle != 0) {
joystick->steam_handle = 0;
joystick->swap_face_buttons = false;
changed = true;
}
}
@@ -2421,6 +2541,15 @@ void SDL_UpdateJoysticks(void)
if (joystick->trigger_rumble_expiration && now >= joystick->trigger_rumble_expiration) {
SDL_RumbleJoystickTriggers(joystick, 0, 0, 0);
joystick->trigger_rumble_resend = 0;
}
if (joystick->trigger_rumble_resend && now >= joystick->trigger_rumble_resend) {
joystick->driver->RumbleTriggers(joystick, joystick->left_trigger_rumble, joystick->right_trigger_rumble);
joystick->trigger_rumble_resend = now + SDL_RUMBLE_RESEND_MS;
if (joystick->trigger_rumble_resend == 0) {
joystick->trigger_rumble_resend = 1;
}
}
}
@@ -2546,158 +2675,14 @@ void SDL_GetJoystickGUIDInfo(SDL_GUID guid, Uint16 *vendor, Uint16 *product, Uin
}
}
static int PrefixMatch(const char *a, const char *b)
{
int matchlen = 0;
while (*a && *b) {
if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) {
++matchlen;
} else {
break;
}
}
return matchlen;
}
char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
{
static struct
{
const char *prefix;
const char *replacement;
} replacements[] = {
{ "ASTRO Gaming", "ASTRO" },
{ "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" },
{ "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" },
{ "HORI CO.,LTD", "HORI" },
{ "HORI CO.,LTD.", "HORI" },
{ "Mad Catz Inc.", "Mad Catz" },
{ "Nintendo Co., Ltd.", "Nintendo" },
{ "NVIDIA Corporation ", "" },
{ "Performance Designed Products", "PDP" },
{ "QANBA USA, LLC", "Qanba" },
{ "QANBA USA,LLC", "Qanba" },
{ "Unknown ", "" },
};
const char *custom_name;
char *name;
size_t i, len;
custom_name = GuessControllerName(vendor, product);
const char *custom_name = GuessControllerName(vendor, product);
if (custom_name) {
return SDL_strdup(custom_name);
}
if (!vendor_name) {
vendor_name = "";
}
if (!product_name) {
product_name = "";
}
while (*vendor_name == ' ') {
++vendor_name;
}
while (*product_name == ' ') {
++product_name;
}
if (*vendor_name && *product_name) {
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
name = (char *)SDL_malloc(len);
if (name) {
(void)SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
}
} else if (*product_name) {
name = SDL_strdup(product_name);
} else if (vendor || product) {
// Couldn't find a controller name, try to give it one based on device type
switch (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, true)) {
case SDL_GAMEPAD_TYPE_XBOX360:
name = SDL_strdup("Xbox 360 Controller");
break;
case SDL_GAMEPAD_TYPE_XBOXONE:
name = SDL_strdup("Xbox One Controller");
break;
case SDL_GAMEPAD_TYPE_PS3:
name = SDL_strdup("PS3 Controller");
break;
case SDL_GAMEPAD_TYPE_PS4:
name = SDL_strdup("PS4 Controller");
break;
case SDL_GAMEPAD_TYPE_PS5:
name = SDL_strdup("DualSense Wireless Controller");
break;
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
name = SDL_strdup("Nintendo Switch Pro Controller");
break;
default:
len = (6 + 1 + 6 + 1);
name = (char *)SDL_malloc(len);
if (name) {
(void)SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
}
break;
}
} else {
name = SDL_strdup("Controller");
}
if (!name) {
return NULL;
}
// Trim trailing whitespace
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
// continue
}
name[len] = '\0';
// Compress duplicate spaces
for (i = 0; i < (len - 1);) {
if (name[i] == ' ' && name[i + 1] == ' ') {
SDL_memmove(&name[i], &name[i + 1], (len - i));
--len;
} else {
++i;
}
}
// Perform any manufacturer replacements
for (i = 0; i < SDL_arraysize(replacements); ++i) {
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);
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;
}
}
/* Remove duplicate manufacturer or product in the name
* e.g. Razer Razer Raiju Tournament Edition Wired
*/
for (i = 1; i < (len - 1); ++i) {
int matchlen = PrefixMatch(name, &name[i]);
while (matchlen > 0) {
if (name[matchlen] == ' ' || name[matchlen] == '-') {
SDL_memmove(name, name + matchlen + 1, len - matchlen);
break;
}
--matchlen;
}
if (matchlen > 0) {
// We matched the manufacturer's name and removed it
break;
}
}
return name;
return SDL_CreateDeviceName(vendor, product, vendor_name, product_name, "Controller");
}
SDL_GUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *vendor_name, const char *product_name, Uint8 driver_signature, Uint8 driver_data)
@@ -2945,7 +2930,8 @@ bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id)
}
if (vendor_id == USB_VENDOR_HORI) {
if (product_id == USB_PRODUCT_HORI_FIGHTING_COMMANDER_OCTA_SERIES_X ||
product_id == USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X) {
product_id == USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X ||
product_id == USB_PRODUCT_HORI_TAIKO_DRUM_CONTROLLER) {
return true;
}
}
+3
View File
@@ -83,6 +83,8 @@ struct SDL_Joystick
SDL_GUID guid _guarded; // Joystick guid
Uint16 firmware_version _guarded; // Firmware version, if available
Uint64 steam_handle _guarded; // Steam controller API handle
bool swap_face_buttons _guarded; // Whether we should swap face buttons
bool is_virtual _guarded; // Whether this is a virtual joystick
int naxes _guarded; // Number of axis controls on the joystick
SDL_JoystickAxisInfo *axes _guarded;
@@ -111,6 +113,7 @@ struct SDL_Joystick
Uint16 left_trigger_rumble _guarded;
Uint16 right_trigger_rumble _guarded;
Uint64 trigger_rumble_expiration _guarded;
Uint64 trigger_rumble_resend _guarded;
Uint8 led_red _guarded;
Uint8 led_green _guarded;
+1 -1
View File
@@ -21,7 +21,6 @@
static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick
{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3
{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1
{ MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream
@@ -96,6 +95,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller, NULL }, // Hitbox Arcade Stick
{ MAKE_CONTROLLER_ID( 0x0c12, 0x1cf6 ), k_eControllerType_PS4Controller, NULL }, // EMIO PS4 Elite Controller
{ MAKE_CONTROLLER_ID( 0x0c12, 0x1e10 ), k_eControllerType_PS4Controller, NULL }, // P4 Wired Gamepad generic knock off - lightbar but not trackpad or gyro
{ MAKE_CONTROLLER_ID( 0x0c12, 0x2e18 ), k_eControllerType_PS4Controller, NULL }, // ZEROPLUS P4 Wired Gamepad
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS (PS4 peripheral but no trackpad/lightbar)
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS V2 w/ Touchpad for PS4
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x020a ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS PS4/PS5 (PS4 mode)
@@ -27,6 +27,7 @@
#include "SDL_iokitjoystick_c.h"
#include "../hidapi/SDL_hidapijoystick_c.h"
#include "../../haptic/darwin/SDL_syshaptic_c.h" // For haptic hot plugging
#include "../usb_ids.h"
#define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick")
@@ -213,6 +214,29 @@ static bool GetHIDScaledCalibratedState(recDevice *pDevice, recElement *pElement
return result;
}
static bool GetHIDScaledCalibratedState_NACON_Revolution_X_Unlimited(recDevice *pDevice, recElement *pElement, SInt32 min, SInt32 max, SInt32 *pValue)
{
if (pElement->minReport == 0 && pElement->maxReport == 255) {
return GetHIDScaledCalibratedState(pDevice, pElement, min, max, pValue);
}
// This device thumbstick axes have an unusual axis range that
// doesn't work with GetHIDScaledCalibratedState() above.
//
// See https://github.com/libsdl-org/SDL/issues/13143 for details
if (GetHIDElementState(pDevice, pElement, pValue)) {
if (*pValue >= 0) {
// Negative axis values range from 32767 (at rest) to 0 (minimum)
*pValue = -32767 + *pValue;
} else if (*pValue < 0) {
// Positive axis values range from -32768 (at rest) to 0 (maximum)
*pValue = 32768 + *pValue;
}
return true;
}
return false;
}
static void JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
{
recDevice *device = (recDevice *)ctx;
@@ -506,6 +530,11 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
pDevice->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, (Uint16)vendor, (Uint16)product, (Uint16)version, manufacturer_string, product_string, 0, 0);
pDevice->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot((Uint16)vendor, (Uint16)product, product_string);
if (vendor == USB_VENDOR_NACON_ALT &&
product == USB_PRODUCT_NACON_REVOLUTION_X_UNLIMITED_BT) {
pDevice->nacon_revolution_x_unlimited = true;
}
array = IOHIDDeviceCopyMatchingElements(hidDevice, NULL, kIOHIDOptionsTypeNone);
if (array) {
AddHIDElements(array, pDevice);
@@ -957,7 +986,11 @@ static void DARWIN_JoystickUpdate(SDL_Joystick *joystick)
i = 0;
while (element) {
goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
if (device->nacon_revolution_x_unlimited) {
goodRead = GetHIDScaledCalibratedState_NACON_Revolution_X_Unlimited(device, element, -32768, 32767, &value);
} else {
goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
}
if (goodRead) {
SDL_SendJoystickAxis(timestamp, joystick, i, value);
}
@@ -72,6 +72,7 @@ struct joystick_hwdata
int instance_id;
SDL_GUID guid;
int steam_virtual_gamepad_slot;
bool nacon_revolution_x_unlimited;
struct joystick_hwdata *pNext; // next device
};
@@ -24,9 +24,7 @@
#include "../SDL_sysjoystick.h"
#include "../usb_ids.h"
#define COBJMACROS
#include <gameinput.h>
#include "../../core/windows/SDL_gameinput.h"
// Default value for SDL_HINT_JOYSTICK_GAMEINPUT
#if defined(SDL_PLATFORM_GDK)
@@ -67,12 +65,10 @@ typedef struct joystick_hwdata
} GAMEINPUT_InternalJoystickHwdata;
static GAMEINPUT_InternalList g_GameInputList = { NULL };
static SDL_SharedObject *g_hGameInputDLL = NULL;
static IGameInput *g_pGameInput = NULL;
static GameInputCallbackToken g_GameInputCallbackToken = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE;
static Uint64 g_GameInputTimestampOffset;
static bool GAMEINPUT_InternalIsGamepad(const GameInputDeviceInfo *info)
{
if (info->supportedInput & GameInputKindGamepad) {
@@ -245,24 +241,8 @@ static bool GAMEINPUT_JoystickInit(void)
return true;
}
if (!g_hGameInputDLL) {
g_hGameInputDLL = SDL_LoadObject("gameinput.dll");
if (!g_hGameInputDLL) {
return false;
}
}
if (!g_pGameInput) {
typedef HRESULT (WINAPI *GameInputCreate_t)(IGameInput * *gameInput);
GameInputCreate_t GameInputCreateFunc = (GameInputCreate_t)SDL_LoadFunction(g_hGameInputDLL, "GameInputCreate");
if (!GameInputCreateFunc) {
return false;
}
hR = GameInputCreateFunc(&g_pGameInput);
if (FAILED(hR)) {
return SDL_SetError("GameInputCreate failure with HRESULT of %08lX", hR);
}
if (!SDL_InitGameInput(&g_pGameInput)) {
return false;
}
hR = IGameInput_RegisterDeviceCallback(g_pGameInput,
@@ -615,6 +595,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
} else {
bool *button_state = SDL_stack_alloc(bool, info->controllerButtonCount);
float *axis_state = SDL_stack_alloc(float, info->controllerAxisCount);
GameInputSwitchPosition *switch_state = SDL_stack_alloc(GameInputSwitchPosition, info->controllerSwitchCount);
if (button_state) {
uint32_t i;
@@ -635,6 +616,46 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
SDL_stack_free(axis_state);
}
#undef CONVERT_AXIS
if (switch_state) {
uint32_t i;
uint32_t switch_count = IGameInputReading_GetControllerSwitchState(reading, info->controllerSwitchCount, switch_state);
for (i = 0; i < switch_count; ++i) {
Uint8 hat;
switch (switch_state[i]) {
case GameInputSwitchUp:
hat = SDL_HAT_UP;
break;
case GameInputSwitchUpRight:
hat = SDL_HAT_UP | SDL_HAT_RIGHT;
break;
case GameInputSwitchRight:
hat = SDL_HAT_RIGHT;
break;
case GameInputSwitchDownRight:
hat = SDL_HAT_DOWN | SDL_HAT_RIGHT;
break;
case GameInputSwitchDown:
hat = SDL_HAT_DOWN;
break;
case GameInputSwitchDownLeft:
hat = SDL_HAT_DOWN | SDL_HAT_LEFT;
break;
case GameInputSwitchLeft:
hat = SDL_HAT_LEFT;
break;
case GameInputSwitchUpLeft:
hat = SDL_HAT_UP | SDL_HAT_LEFT;
break;
case GameInputSwitchCenter:
default:
hat = SDL_HAT_CENTERED;
break;
}
SDL_SendJoystickHat(timestamp, joystick, (Uint8)i, hat);
}
SDL_stack_free(switch_state);
}
}
if (info->supportedInput & GameInputKindTouch) {
@@ -689,14 +710,9 @@ static void GAMEINPUT_JoystickQuit(void)
GAMEINPUT_InternalRemoveByIndex(0);
}
IGameInput_Release(g_pGameInput);
SDL_QuitGameInput();
g_pGameInput = NULL;
}
if (g_hGameInputDLL) {
SDL_UnloadObject(g_hGameInputDLL);
g_hGameInputDLL = NULL;
}
}
static bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
@@ -70,6 +70,8 @@ static bool HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Jo
for (i = 0; i < device->num_children; ++i) {
SDL_HIDAPI_Device *child = device->children[i];
if (!child->driver->OpenJoystick(child, joystick)) {
child->broken = true;
while (i-- > 0) {
child = device->children[i];
child->driver->CloseJoystick(child, joystick);
@@ -31,7 +31,9 @@
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
// Define this if you want to log all packets from the controller
// #define DEBUG_GAMECUBE_PROTOCOL
#if 0
#define DEBUG_GAMECUBE_PROTOCOL
#endif
#define MAX_CONTROLLERS 4
@@ -119,22 +121,15 @@ static bool HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
}
device->context = ctx;
ctx->joysticks[0] = 0;
ctx->joysticks[1] = 0;
ctx->joysticks[2] = 0;
ctx->joysticks[3] = 0;
ctx->rumble[0] = rumbleMagic;
ctx->useRumbleBrake = false;
if (device->vendor_id != USB_VENDOR_NINTENDO) {
ctx->pc_mode = true;
}
if (ctx->pc_mode) {
for (i = 0; i < MAX_CONTROLLERS; ++i) {
ResetAxisRange(ctx, i);
HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
}
ResetAxisRange(ctx, 0);
HIDAPI_JoystickConnected(device, &ctx->joysticks[0]);
} else {
// This is all that's needed to initialize the device. Really!
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
@@ -204,69 +199,61 @@ static void HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device
{
}
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, int size)
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, bool invert_c_stick)
{
SDL_Joystick *joystick;
Uint8 i, v;
const Uint8 i = 0; // We have a separate context for each connected controller in PC mode, just use the first index
Uint8 v;
Sint16 axis_value;
Uint64 timestamp = SDL_GetTicksNS();
if (size != 10) {
return; // How do we handle this packet?
}
i = packet[0] - 1;
if (i >= MAX_CONTROLLERS) {
return; // How do we handle this packet?
}
joystick = SDL_GetJoystickFromID(ctx->joysticks[i]);
if (!joystick) {
// Hasn't been opened yet, skip
return;
}
#define READ_BUTTON(off, flag, button) \
SDL_SendJoystickButton( \
timestamp, \
joystick, \
button, \
#define READ_BUTTON(off, flag, button) \
SDL_SendJoystickButton( \
timestamp, \
joystick, \
button, \
((packet[off] & flag) != 0));
READ_BUTTON(1, 0x02, 0) // A
READ_BUTTON(1, 0x04, 1) // B
READ_BUTTON(1, 0x08, 3) // Y
READ_BUTTON(1, 0x01, 2) // X
READ_BUTTON(2, 0x80, 4) // DPAD_LEFT
READ_BUTTON(2, 0x20, 5) // DPAD_RIGHT
READ_BUTTON(2, 0x40, 6) // DPAD_DOWN
READ_BUTTON(2, 0x10, 7) // DPAD_UP
READ_BUTTON(2, 0x02, 8) // START
READ_BUTTON(1, 0x80, 9) // RIGHTSHOULDER
READ_BUTTON(0, 0x02, 0) // A
READ_BUTTON(0, 0x04, 1) // B
READ_BUTTON(0, 0x08, 3) // Y
READ_BUTTON(0, 0x01, 2) // X
READ_BUTTON(1, 0x80, 4) // DPAD_LEFT
READ_BUTTON(1, 0x20, 5) // DPAD_RIGHT
READ_BUTTON(1, 0x40, 6) // DPAD_DOWN
READ_BUTTON(1, 0x10, 7) // DPAD_UP
READ_BUTTON(1, 0x02, 8) // START
READ_BUTTON(0, 0x80, 9) // RIGHTSHOULDER
/* These two buttons are for the bottoms of the analog triggers.
* More than likely, you're going to want to read the axes instead!
* -flibit
*/
READ_BUTTON(1, 0x20, 10) // TRIGGERRIGHT
READ_BUTTON(1, 0x10, 11) // TRIGGERLEFT
READ_BUTTON(0, 0x20, 10) // TRIGGERRIGHT
READ_BUTTON(0, 0x10, 11) // TRIGGERLEFT
#undef READ_BUTTON
#define READ_AXIS(off, axis, invert) \
v = invert ? (0xff - packet[off]) : packet[off]; \
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
#define READ_AXIS(off, axis, invert) \
v = (invert) ? (0xff - packet[off]) : packet[off]; \
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
axis_value = (Sint16)HIDAPI_RemapVal(v, ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \
SDL_SendJoystickAxis( \
timestamp, \
joystick, \
SDL_SendJoystickAxis( \
timestamp, \
joystick, \
axis, axis_value);
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTX, 0)
READ_AXIS(4, SDL_GAMEPAD_AXIS_LEFTY, 1)
READ_AXIS(6, SDL_GAMEPAD_AXIS_RIGHTX, 0)
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTY, 1)
READ_AXIS(7, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
READ_AXIS(8, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
READ_AXIS(2, SDL_GAMEPAD_AXIS_LEFTX, 0)
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTY, 1)
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTX, invert_c_stick ? 1 : 0)
READ_AXIS(4, SDL_GAMEPAD_AXIS_RIGHTY, invert_c_stick ? 0 : 1)
READ_AXIS(6, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
READ_AXIS(7, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
#undef READ_AXIS
}
@@ -365,7 +352,18 @@ static bool HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
#endif
if (ctx->pc_mode) {
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, size);
if (size == 10) {
// This is the older firmware
// The first byte is the index of the connected controller
// The C stick has an inverted value range compared to the left stick
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, &packet[1], true);
} else if (size == 9) {
// This is the newer firmware (version 0x7)
// The C stick has the same value range compared to the left stick
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, false);
} else {
// How do we handle this packet?
}
} else {
HIDAPI_DriverGameCube_HandleNintendoPacket(device, ctx, packet, size);
}
@@ -1003,8 +1003,8 @@ static bool HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device
static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size)
{
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
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
static const float TOUCHPAD_SCALEY = 1.08695652e-3f; // 1.0f / 920 // This is noted as being 944 resolution, but 920 feels better
Sint16 axis;
bool touchpad_down;
int touchpad_x, touchpad_y;
+15 -10
View File
@@ -812,14 +812,19 @@ static void HIDAPI_DriverPS5_SetEnhancedModeAvailable(SDL_DriverPS5_Context *ctx
}
if (ctx->sensors_supported) {
// Standard DualSense sensor update rate is 250 Hz over USB
float update_rate = 250.0f;
if (ctx->device->is_bluetooth) {
// Bluetooth sensor update rate appears to be 1000 Hz
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, 1000.0f);
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 1000.0f);
} else {
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, 250.0f);
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 250.0f);
update_rate = 1000.0f;
} else if (SDL_IsJoystickDualSenseEdge(ctx->device->vendor_id, ctx->device->product_id)) {
// DualSense Edge sensor update rate is 1000 Hz over USB
update_rate = 1000.0f;
}
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, update_rate);
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, update_rate);
}
ctx->report_battery = true;
@@ -952,7 +957,7 @@ static bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystic
SDL_AddHintCallback(SDL_HINT_JOYSTICK_ENHANCED_REPORTS,
SDL_PS5EnhancedReportsChanged, ctx);
SDL_AddHintCallback(SDL_HINT_JOYSTICK_ENHANCED_REPORTS,
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED,
SDL_PS5PlayerLEDHintChanged, ctx);
return true;
@@ -1355,8 +1360,8 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
static void HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet, Uint64 timestamp)
{
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
static const float TOUCHPAD_SCALEY = 9.34579439e-4f; // 1.0f / 1070
bool touchpad_down;
int touchpad_x, touchpad_y;
@@ -1406,8 +1411,8 @@ static void HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
static void HIDAPI_DriverPS5_HandleStatePacketAlt(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketAlt_t *packet, Uint64 timestamp)
{
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
static const float TOUCHPAD_SCALEY = 9.34579439e-4f; // 1.0f / 1070
bool touchpad_down;
int touchpad_x, touchpad_y;
@@ -58,9 +58,7 @@
#define SWITCH_GYRO_SCALE 14.2842f
#define SWITCH_ACCEL_SCALE 4096.f
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
#define SWITCH_GYRO_SCALE_MULT 936.0f
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
#define SWITCH_ACCEL_SCALE_MULT 4.0f
enum
@@ -813,6 +811,12 @@ static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx)
}
break;
}
// Wired controllers break if they are put into simple controller state
if (input_mode == k_eSwitchInputReportIDs_SimpleControllerState &&
!ctx->device->is_bluetooth) {
input_mode = k_eSwitchInputReportIDs_FullControllerState;
}
return input_mode;
}
@@ -869,33 +873,22 @@ static void SetEnhancedModeAvailable(SDL_DriverSwitch_Context *ctx)
}
}
static void SetEnhancedMode(SDL_DriverSwitch_Context *ctx, bool bEnabled)
{
if (bEnabled) {
SetEnhancedModeAvailable(ctx);
}
if (bEnabled != ctx->m_bEnhancedMode) {
ctx->m_bEnhancedMode = bEnabled;
UpdateInputMode(ctx);
}
}
static void SetEnhancedReportHint(SDL_DriverSwitch_Context *ctx, HIDAPI_Switch_EnhancedReportHint eEnhancedReportHint)
{
ctx->m_eEnhancedReportHint = eEnhancedReportHint;
switch (eEnhancedReportHint) {
case SWITCH_ENHANCED_REPORT_HINT_OFF:
SetEnhancedMode(ctx, false);
ctx->m_bEnhancedMode = false;
break;
case SWITCH_ENHANCED_REPORT_HINT_ON:
SetEnhancedMode(ctx, true);
SetEnhancedModeAvailable(ctx);
ctx->m_bEnhancedMode = true;
break;
case SWITCH_ENHANCED_REPORT_HINT_AUTO:
SetEnhancedModeAvailable(ctx);
break;
}
ctx->m_eEnhancedReportHint = eEnhancedReportHint;
UpdateInputMode(ctx);
}
@@ -935,13 +928,14 @@ static bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, bool enabled)
static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
{
Uint8 *pLeftStickCal;
Uint8 *pRightStickCal;
Uint8 *pLeftStickCal = NULL;
Uint8 *pRightStickCal = NULL;
size_t stick, axis;
SwitchSubcommandInputPacket_t *user_reply = NULL;
SwitchSubcommandInputPacket_t *factory_reply = NULL;
SwitchSPIOpData_t readUserParams;
SwitchSPIOpData_t readFactoryParams;
Uint8 userParamsReadSuccessCount = 0;
// Read User Calibration Info
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
@@ -954,21 +948,46 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
return false;
}
// Automatically select the user calibration if magic bytes are set
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
} else {
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
}
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
userParamsReadSuccessCount += 1;
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
} else {
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
}
// Only read the factory calibration info if we failed to receive the correct magic bytes
if (userParamsReadSuccessCount < 2) {
// Read Factory Calibration Info
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
const int MAX_ATTEMPTS = 3;
for (int attempt = 0;; ++attempt) {
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
return false;
}
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
// We successfully read the calibration data
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
break;
}
if (attempt == MAX_ATTEMPTS) {
return false;
}
}
}
// If we still don't have calibration data, return false
if (pLeftStickCal == NULL || pRightStickCal == NULL)
{
return false;
}
/* Stick calibration values are 12-bits each and are packed by bit
@@ -1037,6 +1056,8 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
Uint8 *pIMUScale;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
Sint16 sAccelSensCoeffX, sAccelSensCoeffY, sAccelSensCoeffZ;
Sint16 sGyroSensCoeffX, sGyroSensCoeffY, sGyroSensCoeffZ;
// IMU scale gives us multipliers for converting raw values to real world values
pIMUScale = reply->spiReadData.rgucReadData;
@@ -1045,10 +1066,18 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4];
sAccelSensCoeffX = (pIMUScale[7] << 8) | pIMUScale[6];
sAccelSensCoeffY = (pIMUScale[9] << 8) | pIMUScale[8];
sAccelSensCoeffZ = (pIMUScale[11] << 8) | pIMUScale[10];
sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12];
sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16];
sGyroSensCoeffX = (pIMUScale[19] << 8) | pIMUScale[18];
sGyroSensCoeffY = (pIMUScale[21] << 8) | pIMUScale[20];
sGyroSensCoeffZ = (pIMUScale[23] << 8) | pIMUScale[22];
// Check for user calibration data. If it's present and set, it'll override the factory settings
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
@@ -1065,14 +1094,14 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
}
// Accelerometer scale
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffX - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffY - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffZ - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
// Gyro scale
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * SDL_PI_F / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * SDL_PI_F / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * SDL_PI_F / 180.0f;
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffX - (float)sGyroRawX) * SDL_PI_F / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffY - (float)sGyroRawY) * SDL_PI_F / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffZ - (float)sGyroRawZ) * SDL_PI_F / 180.0f;
} else {
// Use default values
@@ -1094,14 +1123,17 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
{
sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter;
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
if (sRawValue >= 0) {
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
} else {
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
}
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
}
static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
@@ -1111,14 +1143,17 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
sRawValue -= usJoystickCenter;
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
if (sRawValue >= 0) {
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
} else {
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
}
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
}
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
}
static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
@@ -1519,6 +1554,10 @@ static bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joys
ctx->m_bSyncWrite = true;
if (!ctx->m_bInputOnly) {
#ifdef SDL_PLATFORM_MACOS
// Wait for the OS to finish its handshake with the controller
SDL_Delay(250);
#endif
GetInitialInputMode(ctx);
ctx->m_nCurrentInputMode = ctx->m_nInitialInputMode;
@@ -2727,6 +2766,7 @@ static bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
// Reconnect the Bluetooth device once the USB device is gone
if (device->num_joysticks == 0 && device->is_bluetooth && packet_count > 0 &&
!device->parent &&
!HIDAPI_HasConnectedUSBDevice(device->serial)) {
HIDAPI_JoystickConnected(device, NULL);
}
@@ -363,7 +363,7 @@ static SDL_HIDAPI_Device *HIDAPI_GetDeviceByIndex(int device_index, SDL_Joystick
SDL_AssertJoysticksLocked();
for (device = SDL_HIDAPI_devices; device; device = device->next) {
if (device->parent) {
if (device->parent || device->broken) {
continue;
}
if (device->driver) {
@@ -533,24 +533,6 @@ static bool HIDAPI_JoystickInit(void)
return true;
}
#ifdef SDL_USE_LIBUDEV
if (linux_enumeration_method == ENUMERATION_UNSET) {
if (!SDL_GetHintBoolean(SDL_HINT_HIDAPI_UDEV, true)) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"udev disabled by SDL_HINT_HIDAPI_UDEV");
linux_enumeration_method = ENUMERATION_FALLBACK;
} else if (SDL_GetSandbox() != SDL_SANDBOX_NONE) {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Container detected, disabling HIDAPI udev integration");
linux_enumeration_method = ENUMERATION_FALLBACK;
} else {
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
"Using udev for HIDAPI joystick device discovery");
linux_enumeration_method = ENUMERATION_LIBUDEV;
}
}
#endif
if (SDL_hid_init() < 0) {
return SDL_SetError("Couldn't initialize hidapi");
}
@@ -703,7 +685,7 @@ bool HIDAPI_HasConnectedUSBDevice(const char *serial)
}
for (device = SDL_HIDAPI_devices; device; device = device->next) {
if (!device->driver) {
if (!device->driver || device->broken) {
continue;
}
@@ -729,7 +711,7 @@ void HIDAPI_DisconnectBluetoothDevice(const char *serial)
}
for (device = SDL_HIDAPI_devices; device; device = device->next) {
if (!device->driver) {
if (!device->driver || device->broken) {
continue;
}
@@ -769,11 +751,12 @@ bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoysti
++SDL_HIDAPI_numjoysticks;
SDL_PrivateJoystickAdded(joystickID);
if (pJoystickID) {
*pJoystickID = joystickID;
}
SDL_PrivateJoystickAdded(joystickID);
return true;
}
@@ -886,10 +869,8 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
return NULL;
}
SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, true);
device->path = SDL_strdup(info->path);
if (!device->path) {
SDL_free(device);
return NULL;
if (info->path) {
device->path = SDL_strdup(info->path);
}
device->seen = true;
device->vendor_id = info->vendor_id;
@@ -1034,6 +1015,10 @@ static bool HIDAPI_CreateCombinedJoyCons(void)
// This device is already part of a combined device
continue;
}
if (device->broken) {
// This device can't be used
continue;
}
SDL_GetJoystickGUIDInfo(device->guid, &vendor, &product, NULL, NULL);
@@ -1067,6 +1052,11 @@ static bool HIDAPI_CreateCombinedJoyCons(void)
info.usage = USB_USAGE_GENERIC_GAMEPAD;
info.manufacturer_string = L"Nintendo";
info.product_string = L"Switch Joy-Con (L/R)";
if (children[0]->is_bluetooth || children[1]->is_bluetooth) {
info.bus_type = SDL_HID_API_BUS_BLUETOOTH;
} else {
info.bus_type = SDL_HID_API_BUS_USB;
}
combined = HIDAPI_AddDevice(&info, 2, children);
if (combined && combined->driver) {
@@ -1149,11 +1139,18 @@ check_removed:
goto check_removed;
} else {
HIDAPI_DelDevice(device);
device = NULL;
// Update the device list again in case this device comes back
SDL_HIDAPI_change_count = 0;
}
}
if (device && device->broken && device->parent) {
HIDAPI_DelDevice(device->parent);
// We deleted a different device here, restart the loop
goto check_removed;
}
device = next;
}
@@ -1496,7 +1493,7 @@ static bool HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index)
SDL_AssertJoysticksLocked();
if (!device || !device->driver) {
if (!device || !device->driver || device->broken) {
// This should never happen - validated before being called
return SDL_SetError("Couldn't find HIDAPI device at index %d", device_index);
}
@@ -101,6 +101,10 @@ typedef struct SDL_HIDAPI_Device
// Used to flag that the device is being updated
bool updating;
// Used to flag devices that failed open
// This can happen on Windows with Bluetooth devices that have turned off
bool broken;
struct SDL_HIDAPI_Device *parent;
int num_children;
struct SDL_HIDAPI_Device **children;
@@ -1518,6 +1518,7 @@ static SDL_sensorlist_item *GetSensor(SDL_joylist_item *item)
return NULL;
}
if (ioctl(fd_item, EVIOCGUNIQ(sizeof(uniq_item) - 1), &uniq_item) < 0) {
close(fd_item);
return NULL;
}
close(fd_item);
+2
View File
@@ -76,6 +76,7 @@
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184
#define USB_PRODUCT_HORI_STEAM_CONTROLLER 0x01AB
#define USB_PRODUCT_HORI_STEAM_CONTROLLER_BT 0x0196
#define USB_PRODUCT_HORI_TAIKO_DRUM_CONTROLLER 0x01b2
#define USB_PRODUCT_LOGITECH_F310 0xc216
#define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1
#define USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK 0x2218
@@ -83,6 +84,7 @@
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRED 0x0d17
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS 0x0d18
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRED 0x0d19
#define USB_PRODUCT_NACON_REVOLUTION_X_UNLIMITED_BT 0x0689
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019
#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e
@@ -40,11 +40,7 @@
#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF)
// external variables referenced.
#ifdef SDL_VIDEO_DRIVER_WINDOWS
extern HWND SDL_HelperWindow;
#else
static const HWND SDL_HelperWindow = NULL;
#endif
// local variables
static bool coinitialized = false;
@@ -158,8 +158,11 @@ struct joystick_hwdata
Uint8 wgi_correlation_count;
Uint8 wgi_uncorrelate_count;
WindowsGamingInputGamepadState *wgi_slot;
struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration;
#endif
bool triggers_rumbling;
SDL_RAWINPUT_Device *device;
};
typedef struct joystick_hwdata RAWINPUT_DeviceContext;
@@ -447,7 +450,6 @@ typedef struct WindowsGamingInputGamepadState
bool used; // Is currently mapped to an SDL device
bool connected; // Just used during update to track disconnected
Uint8 correlation_id;
struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration;
} WindowsGamingInputGamepadState;
static struct
@@ -909,9 +911,11 @@ static void RAWINPUT_AddDevice(HANDLE hDevice)
char *product_string = NULL;
WCHAR string[128];
string[0] = 0;
if (SDL_HidD_GetManufacturerString(hFile, string, sizeof(string))) {
manufacturer_string = WIN_StringToUTF8W(string);
}
string[0] = 0;
if (SDL_HidD_GetProductString(hFile, string, sizeof(string))) {
product_string = WIN_StringToUTF8W(string);
}
@@ -1026,7 +1030,7 @@ static bool RAWINPUT_JoystickInit(void)
{
SDL_assert(!SDL_RAWINPUT_inited);
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, true)) {
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, false)) {
return true;
}
@@ -1459,7 +1463,7 @@ static bool RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
// Prefer XInput over WGI because it allows rumble in the background
if (!rumbled && ctx->xinput_correlated) {
if (!rumbled && ctx->xinput_correlated && !ctx->triggers_rumbling) {
XINPUT_VIBRATION XVibration;
if (!XINPUTSETSTATE) {
@@ -1477,12 +1481,12 @@ static bool RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency
#endif // SDL_JOYSTICK_RAWINPUT_XINPUT
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
// Save off the motor state in case trigger rumble is started
ctx->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
ctx->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
if (!rumbled && ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr;
gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, ctx->vibration);
if (SUCCEEDED(hr)) {
rumbled = true;
}
@@ -1504,15 +1508,15 @@ static bool RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
RAWINPUT_DeviceContext *ctx = joystick->hwdata;
ctx->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16;
ctx->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16;
if (ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr;
gamepad_state->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16;
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);
HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, ctx->vibration);
if (!SUCCEEDED(hr)) {
return SDL_SetError("Setting vibration failed: 0x%lx", hr);
}
ctx->triggers_rumbling = (left_rumble > 0 || right_rumble > 0);
return true;
} else {
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");