Update SDL3 from 3.2.4 to 3.2.20
This commit is contained in:
@@ -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();
|
||||
{
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user