diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 2eca81208..87f08b203 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -363,6 +363,10 @@ typedef enum SDL_CONTROLLER_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_AUX1, // Xbox Elite paddle, Nintendo Switch Pro capture button + SDL_CONTROLLER_BUTTON_AUX2, // Xbox Elite paddle + SDL_CONTROLLER_BUTTON_AUX3, // Xbox Elite paddle + SDL_CONTROLLER_BUTTON_AUX4, // Xbox Elite paddle SDL_CONTROLLER_BUTTON_MAX } SDL_GameControllerButton; diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 81c387416..4967ce583 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -29,6 +29,7 @@ #include "SDL_sysjoystick.h" #include "SDL_joystick_c.h" #include "SDL_gamecontrollerdb.h" +#include "usb_ids.h" #if !SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" @@ -105,7 +106,6 @@ typedef struct _ControllerMapping_t static SDL_JoystickGUID s_zeroGUID; static ControllerMapping_t *s_pSupportedControllers = NULL; static ControllerMapping_t *s_pDefaultMapping = NULL; -static ControllerMapping_t *s_pHIDAPIMapping = NULL; static ControllerMapping_t *s_pXInputMapping = NULL; /* The SDL game controller structure */ @@ -193,6 +193,7 @@ SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, c SDL_LoadVIDPIDListFromHint(hint, &SDL_allowed_controllers); } +static ControllerMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority); static int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value); static int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state); @@ -450,37 +451,199 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * ev return 1; } +#ifdef __ANDROID__ +/* + * Helper function to guess at a mapping based on the elements reported for this controller + */ +static ControllerMapping_t *SDL_CreateMappingForAndroidController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + int button_mask; + int axis_mask; + + button_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-4])); + axis_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-2])); + if (!button_mask && !axis_mask) { + /* Accelerometer, shouldn't have a game controller mapping */ + return NULL; + } + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) { + SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) { + SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string)); + } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { + /* Use the back button as "B" for easy UI navigation with TV remotes */ + SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string)); + button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) { + SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) { + SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { + SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) { + /* The guide button generally isn't functional (or acts as a home button) on most Android controllers before Android 11 */ + if (SDL_GetAndroidSDKVersion() >= 30 /* Android 11 */) { + SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string)); + } + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) { + SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) { + SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) { + SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) { + SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) { + SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) { + SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) { + SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) { + SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) { + SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) { + SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) { + SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) { + SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) { + SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) { + SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { + SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string)); + } + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, + &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} +#endif /* __ANDROID__ */ + +/* + * Helper function to guess at a mapping for HIDAPI controllers + */ +static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + Uint16 vendor; + Uint16 product; + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); + + if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) { + /* GameCube driver has 12 buttons and 6 axes */ + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string)); + } else { + /* All other controllers have the standard set of 19 buttons and 6 axes */ + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + + if (SDL_IsJoystickXboxOneElite(vendor, product)) { + /* XBox One Elite Controllers have 4 back paddle buttons */ + SDL_strlcat(mapping_string, "aux1:b15,aux2:b16,aux3:b17,aux4:b18,", sizeof(mapping_string)); + } else if (SDL_IsJoystickSteamController(vendor, product)) { + /* Steam controllers have 2 back paddle buttons */ + SDL_strlcat(mapping_string, "aux1:b15,aux2:b16,", sizeof(mapping_string)); + } else { + switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) { + case SDL_CONTROLLER_TYPE_PS4: + case SDL_CONTROLLER_TYPE_PS5: + /* PS4/PS5 controllers have an additional touchpad button */ + SDL_strlcat(mapping_string, "aux1:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + /* Nintendo Switch Pro controllers have a screenshot button */ + SDL_strlcat(mapping_string, "aux1:b15,", sizeof(mapping_string)); + break; + default: + break; + } + } + } + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, + &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + +/* + * Helper function to guess at a mapping for RAWINPUT controllers + */ +static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, + &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + /* * Helper function to scan the mappings database for a controller with the specified GUID */ -static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid, SDL_bool exact_match) +static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool exact_match) { - ControllerMapping_t *pSupportedController = s_pSupportedControllers; - while (pSupportedController) { - if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) { - return pSupportedController; + ControllerMapping_t *mapping = s_pSupportedControllers; + + while (mapping) { + if (SDL_memcmp(&guid, &mapping->guid, sizeof(guid)) == 0) { + return mapping; } - pSupportedController = pSupportedController->next; + mapping = mapping->next; } + if (!exact_match) { - if (SDL_IsJoystickHIDAPI(*guid)) { - /* This is a HIDAPI device */ - return s_pHIDAPIMapping; - } -#if SDL_JOYSTICK_RAWINPUT - if (SDL_IsJoystickRAWINPUT(*guid)) { - /* This is a RAWINPUT device - same data as HIDAPI */ - return s_pHIDAPIMapping; - } -#endif #if SDL_JOYSTICK_XINPUT - if (SDL_IsJoystickXInput(*guid)) { + if (SDL_IsJoystickXInput(guid)) { /* This is an XInput device */ return s_pXInputMapping; } #endif +#ifdef __ANDROID__ + if (!mapping && !SDL_IsJoystickHIDAPI(guid)) { + mapping = SDL_CreateMappingForAndroidController(guid); + } +#endif + if (!mapping && SDL_IsJoystickHIDAPI(guid)) { + mapping = SDL_CreateMappingForHIDAPIController(guid); + } + if (!mapping && SDL_IsJoystickRAWINPUT(guid)) { + mapping = SDL_CreateMappingForRAWINPUTController(guid); + } } - return NULL; + return mapping; } static const char* map_StringForControllerAxis[] = { @@ -542,6 +705,10 @@ static const char* map_StringForControllerButton[] = { "dpdown", "dpleft", "dpright", + "aux1", + "aux2", + "aux3", + "aux4", NULL }; @@ -880,7 +1047,7 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, return NULL; } - pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID, SDL_TRUE); + pControllerMapping = SDL_PrivateGetControllerMappingForGUID(jGUID, SDL_TRUE); if (pControllerMapping) { /* Only overwrite the mapping if the priority is the same or higher. */ if (pControllerMapping->priority <= priority) { @@ -929,123 +1096,6 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, return pControllerMapping; } -#ifdef __ANDROID__ -/* - * Helper function to guess at a mapping based on the elements reported for this controller - */ -static ControllerMapping_t *SDL_CreateMappingForAndroidController(const char *name, SDL_JoystickGUID guid) -{ - SDL_bool existing; - char name_string[128]; - char mapping_string[1024]; - int button_mask; - int axis_mask; - - button_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-4])); - axis_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-2])); - if (!button_mask && !axis_mask) { - /* Accelerometer, shouldn't have a game controller mapping */ - return NULL; - } - - /* Remove any commas in the name */ - SDL_strlcpy(name_string, name, sizeof(name_string)); - { - char *spot; - for (spot = name_string; *spot; ++spot) { - if (*spot == ',') { - *spot = ' '; - } - } - } - SDL_snprintf(mapping_string, sizeof(mapping_string), "none,%s,", name_string); - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) { - SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) { - SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string)); - } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { - /* Use the back button as "B" for easy UI navigation with TV remotes */ - SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string)); - button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) { - SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) { - SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { - SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) { - /* The guide button generally isn't functional (or acts as a home button) on most Android controllers before Android 11 */ - if (SDL_GetAndroidSDKVersion() >= 30 /* Android 11 */) { - SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string)); - } - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) { - SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) { - SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) { - SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) { - SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) { - SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) { - SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) { - SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) { - SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string)); - } - if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) { - SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) { - SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) { - SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) { - SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) { - SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) { - SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string)); - } - if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { - SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string)); - } - - /* Remove trailing comma */ - { - int pos = (int)SDL_strlen(mapping_string) - 1; - if (pos >= 0) { - if (mapping_string[pos] == ',') { - mapping_string[pos] = '\0'; - } - } - } - - return SDL_PrivateAddMappingForGUID(guid, mapping_string, - &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); -} -#endif /* __ANDROID__ */ - - /* * Helper function to determine pre-calculated offset to certain joystick mappings */ @@ -1053,7 +1103,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const { ControllerMapping_t *mapping; - mapping = SDL_PrivateGetControllerMappingForGUID(&guid, SDL_FALSE); + mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE); #ifdef __LINUX__ if (!mapping && name) { if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) { @@ -1071,11 +1121,6 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const mapping = s_pXInputMapping; } } -#ifdef __ANDROID__ - if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) { - mapping = SDL_CreateMappingForAndroidController(name, guid); - } -#endif if (!mapping) { mapping = s_pDefaultMapping; } @@ -1277,7 +1322,6 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap char *pchGUID; SDL_JoystickGUID jGUID; SDL_bool is_default_mapping = SDL_FALSE; - SDL_bool is_hidapi_mapping = SDL_FALSE; SDL_bool is_xinput_mapping = SDL_FALSE; SDL_bool existing = SDL_FALSE; ControllerMapping_t *pControllerMapping; @@ -1354,8 +1398,6 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap } if (!SDL_strcasecmp(pchGUID, "default")) { is_default_mapping = SDL_TRUE; - } else if (!SDL_strcasecmp(pchGUID, "hidapi")) { - is_hidapi_mapping = SDL_TRUE; } else if (!SDL_strcasecmp(pchGUID, "xinput")) { is_xinput_mapping = SDL_TRUE; } @@ -1372,8 +1414,6 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap } else { if (is_default_mapping) { s_pDefaultMapping = pControllerMapping; - } else if (is_hidapi_mapping) { - s_pHIDAPIMapping = pControllerMapping; } else if (is_xinput_mapping) { s_pXInputMapping = pControllerMapping; } @@ -1448,7 +1488,7 @@ char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid) { char *pMappingString = NULL; - ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid, SDL_FALSE); + ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE); if (mapping) { char pchGUID[33]; size_t needed; diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 1f2e263c1..359d4cad2 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -841,7 +841,6 @@ static const char *s_ControllerMappings [] = #if defined(SDL_JOYSTICK_EMSCRIPTEN) "default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", #endif - "hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", NULL }; diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index c4904f185..e48303707 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1735,12 +1735,13 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc if (type == SDL_CONTROLLER_TYPE_UNKNOWN) { if (vendor == 0x0000 && product == 0x0000) { /* Some devices are only identifiable by their name */ - if (SDL_strcmp(name, "Lic Pro Controller") == 0 || - SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 || - SDL_strcmp(name, "Wireless Gamepad") == 0) { + if (name && + (SDL_strcmp(name, "Lic Pro Controller") == 0 || + SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 || + SDL_strcmp(name, "Wireless Gamepad") == 0)) { /* HORI or PowerA Switch Pro Controller clone */ type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; - } else if (SDL_strcmp(name, "Virtual Joystick") == 0) { + } else if (name && SDL_strcmp(name, "Virtual Joystick") == 0) { type = SDL_CONTROLLER_TYPE_VIRTUAL; } else { type = SDL_CONTROLLER_TYPE_UNKNOWN; @@ -1779,6 +1780,25 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc return type; } +SDL_bool +SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_MICROSOFT) { + if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool +SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return (eType == k_eControllerType_PS4Controller); +} + SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id) { @@ -1786,6 +1806,14 @@ SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id) return (eType == k_eControllerType_PS5Controller); } +SDL_bool +SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return (eType == k_eControllerType_SwitchProController || + eType == k_eControllerType_SwitchInputOnlyController); +} + SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id) { diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 301e0c94f..4f31c3a1c 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -61,10 +61,17 @@ extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *v extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name); extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol); +/* Function to return whether a joystick is an Xbox One Elite controller */ +extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a PS4 controller */ +extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id); + /* Function to return whether a joystick is a PS5 controller */ extern SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is a Nintendo Switch Pro controller */ +extern SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id); extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is a Steam Controller */ diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 2f967fe05..23107f005 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -138,16 +138,16 @@ keycode_to_SDL(int keycode) button = SDL_CONTROLLER_BUTTON_GUIDE; break; case AKEYCODE_BUTTON_L2: - button = SDL_CONTROLLER_BUTTON_MAX; /* Not supported by GameController */ + button = SDL_CONTROLLER_BUTTON_AUX1; break; case AKEYCODE_BUTTON_R2: - button = SDL_CONTROLLER_BUTTON_MAX+1; /* Not supported by GameController */ + button = SDL_CONTROLLER_BUTTON_AUX2; break; case AKEYCODE_BUTTON_C: - button = SDL_CONTROLLER_BUTTON_MAX+2; /* Not supported by GameController */ + button = SDL_CONTROLLER_BUTTON_AUX3; break; case AKEYCODE_BUTTON_Z: - button = SDL_CONTROLLER_BUTTON_MAX+3; /* Not supported by GameController */ + button = SDL_CONTROLLER_BUTTON_AUX4; break; /* D-Pad key codes (API 1) */ @@ -165,7 +165,7 @@ keycode_to_SDL(int keycode) break; case AKEYCODE_DPAD_CENTER: /* This is handled better by applications as the A button */ - /*button = SDL_CONTROLLER_BUTTON_MAX+4;*/ /* Not supported by GameController */ + /*button = 19;*/ /* Not supported by GameController */ button = SDL_CONTROLLER_BUTTON_A; break; @@ -186,7 +186,7 @@ keycode_to_SDL(int keycode) case AKEYCODE_BUTTON_14: case AKEYCODE_BUTTON_15: case AKEYCODE_BUTTON_16: - button = keycode - AKEYCODE_BUTTON_1 + SDL_CONTROLLER_BUTTON_MAX + 5; + button = 20 + (keycode - AKEYCODE_BUTTON_1); break; default: diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index f3910bf29..635770fb5 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -68,28 +68,6 @@ typedef struct { /* Define this if you want to log all packets from the controller */ /*#define DEBUG_PS5_PROTOCOL*/ -#ifdef DEBUG_PS5_PROTOCOL -static void -DumpPacket(const char *prefix, Uint8 *data, int size) -{ - int i; - char *buffer; - size_t length = SDL_strlen(prefix) + 11*(USB_PACKET_LENGTH/8) + (5*USB_PACKET_LENGTH) + 1 + 1; - - buffer = (char *)SDL_malloc(length); - SDL_snprintf(buffer, length, prefix, size); - for (i = 0; i < size; ++i) { - if ((i % 8) == 0) { - SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), "\n%.2d: ", i); - } - SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), " 0x%.2x", data[i]); - } - SDL_strlcat(buffer, "\n", length); - SDL_Log("%s", buffer); - SDL_free(buffer); -} -#endif /* DEBUG_PS5_PROTOCOL */ - static SDL_bool HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { @@ -371,7 +349,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_PS5_PROTOCOL - DumpPacket("PS5 packet: size = %d", data, size); + HIDAPI_DumpPacket("PS5 packet: size = %d", data, size); #endif switch (data[0]) { case 0x01: diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index b28e39571..8089b22e2 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1010,7 +1010,7 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic InitializeSteamControllerPacketAssembler(&ctx->m_assembler); /* Initialize the joystick capabilities */ - joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; + joystick->nbuttons = 17; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; return SDL_TRUE; @@ -1111,6 +1111,10 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (ctx->m_state.ulButtons & STEAM_JOYSTICK_BUTTON_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX1, + (ctx->m_state.ulButtons & STEAM_BUTTON_BACK_LEFT_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX2, + (ctx->m_state.ulButtons & STEAM_BUTTON_BACK_RIGHT_MASK) ? SDL_PRESSED : SDL_RELEASED); } { /* Minimum distance from center of pad to register a direction */ diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 4b33e13c5..32a298eea 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -38,6 +38,10 @@ #ifdef SDL_JOYSTICK_HIDAPI_SWITCH +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_SWITCH_PROTOCOL*/ +#define DEBUG_SWITCH_PROTOCOL + /* Define this to get log output for rumble logic */ /*#define DEBUG_RUMBLE*/ @@ -800,7 +804,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti SDL_GameControllerButtonReportingHintChanged, ctx); /* Initialize the joystick capabilities */ - joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; + joystick->nbuttons = 16; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; @@ -960,6 +964,7 @@ static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwi SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); } if (packet->ucStickHat != ctx->m_lastInputOnlyState.ucStickHat) { @@ -1058,6 +1063,7 @@ static void HandleSimpleControllerState(SDL_Joystick *joystick, SDL_DriverSwitch SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); } if (packet->ucStickHat != ctx->m_lastSimpleState.ucStickHat) { @@ -1142,6 +1148,7 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); } if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) { @@ -1210,6 +1217,9 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device) } while ((size = ReadInput(ctx)) > 0) { +#ifdef DEBUG_SWITCH_PROTOCOL + HIDAPI_DumpPacket("Nintendo Switch packet: size = %d", ctx->m_rgucReadBuffer, size); +#endif if (ctx->m_bInputOnly) { HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]); } else { diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c index b82f793a2..6371f55cb 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -708,7 +708,7 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst } /* Initialize the joystick capabilities */ - joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; + joystick->nbuttons = 15; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c index 6e4b70cb7..87357d215 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -136,7 +136,7 @@ HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys SDL_zeroa(ctx->last_state); /* Initialize the joystick capabilities */ - joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; + joystick->nbuttons = 15; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 5c2ecdee2..c60b9a1ff 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -128,28 +128,6 @@ typedef struct { } SDL_DriverXboxOne_Context; -#ifdef DEBUG_XBOX_PROTOCOL -static void -DumpPacket(const char *prefix, Uint8 *data, int size) -{ - int i; - char *buffer; - size_t length = SDL_strlen(prefix) + 11*(USB_PACKET_LENGTH/8) + (5*USB_PACKET_LENGTH) + 1 + 1; - - buffer = (char *)SDL_malloc(length); - SDL_snprintf(buffer, length, prefix, size); - for (i = 0; i < size; ++i) { - if ((i % 8) == 0) { - SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), "\n%.2d: ", i); - } - SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), " 0x%.2x", data[i]); - } - SDL_strlcat(buffer, "\n", length); - SDL_Log("%s", buffer); - SDL_free(buffer); -} -#endif /* DEBUG_XBOX_PROTOCOL */ - static SDL_bool IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id) { @@ -167,13 +145,7 @@ IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id) static SDL_bool ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id) { - if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 || - product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2) { - return SDL_TRUE; - } - } - return SDL_FALSE; + return SDL_IsJoystickXboxOneElite(vendor_id, product_id); } /* Return true if this controller sends the 0x02 "waiting for init" packet */ @@ -244,7 +216,7 @@ SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_XBOX_PROTOCOL - DumpPacket("Xbox One INIT packet: size = %d", data, size); + HIDAPI_DumpPacket("Xbox One INIT packet: size = %d", data, size); #endif if (size >= 2 && data[0] == packet->response[0] && data[1] == packet->response[1]) { got_response = SDL_TRUE; @@ -329,7 +301,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id); /* Initialize the joystick capabilities */ - joystick->nbuttons = ctx->has_paddles ? SDL_CONTROLLER_BUTTON_MAX : (SDL_CONTROLLER_BUTTON_MAX + 4); + joystick->nbuttons = ctx->has_paddles ? 19 : 15; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; @@ -462,10 +434,10 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, } if (ctx->last_state[paddle_index] != data[paddle_index]) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+0, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+1, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+2, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MAX+3, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX1, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX2, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX3, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_AUX4, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED); } } @@ -740,7 +712,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device) while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { #ifdef DEBUG_XBOX_PROTOCOL - DumpPacket("Xbox One packet: size = %d", data, size); + HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size); #endif if (ctx->bluetooth) { switch (data[0]) { diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 3872b6a1c..9dcfe5c75 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -390,6 +390,26 @@ HIDAPI_ShutdownDiscovery() #endif } +void +HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size) +{ + int i; + char *buffer; + size_t length = SDL_strlen(prefix) + 11*(USB_PACKET_LENGTH/8) + (5*USB_PACKET_LENGTH) + 1 + 1; + + buffer = (char *)SDL_malloc(length); + SDL_snprintf(buffer, length, prefix, size); + for (i = 0; i < size; ++i) { + if ((i % 8) == 0) { + SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), "\n%.2d: ", i); + } + SDL_snprintf(&buffer[SDL_strlen(buffer)], length - SDL_strlen(buffer), " 0x%.2x", data[i]); + } + SDL_strlcat(buffer, "\n", length); + SDL_Log("%s", buffer); + SDL_free(buffer); +} + static void HIDAPI_JoystickDetect(void); static void HIDAPI_JoystickClose(SDL_Joystick * joystick); diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 5b13c2007..9a2136b7b 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -124,6 +124,8 @@ extern void HIDAPI_UpdateDevices(void); extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID, SDL_bool is_external); extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID, SDL_bool is_external); +extern void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size); + #endif /* SDL_JOYSTICK_HIDAPI_H */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/test/controllermap.c b/test/controllermap.c index 9e3ae32f5..48587e541 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -74,6 +74,10 @@ static struct { 154, 249, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_DOWN */ { 116, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_LEFT */ { 186, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_RIGHT */ + { 158, 0, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_AUX1 */ + { 208, 0, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_AUX2 */ + { 258, 0, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_AUX3 */ + { 308, 0, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_AUX4 */ { 74, 153, 270.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTX_NEGATIVE */ { 74, 153, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTX_POSITIVE */ { 74, 153, 0.0, MARKER_AXIS }, /* SDL_CONTROLLER_BINDING_AXIS_LEFTY_NEGATIVE */ @@ -112,6 +116,10 @@ static int s_arrBindingOrder[BINDING_COUNT] = { SDL_CONTROLLER_BUTTON_BACK, SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_AUX1, + SDL_CONTROLLER_BUTTON_AUX2, + SDL_CONTROLLER_BUTTON_AUX3, + SDL_CONTROLLER_BUTTON_AUX4, }; typedef struct diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index 9a3c95704..7b3a88071 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -49,6 +49,10 @@ static const struct { int x; int y; } button_positions[] = { {154, 249}, /* DPAD_DOWN */ {116, 217}, /* DPAD_LEFT */ {186, 217}, /* DPAD_RIGHT */ + {158, 0}, /* AUX1 */ + {208, 0}, /* AUX2 */ + {258, 0}, /* AUX3 */ + {308, 0}, /* AUX4 */ }; /* This is indexed by SDL_GameControllerAxis. */