@@ -714,7 +714,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
714714 product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 ||
715715 product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3 ))) {
716716 // GameCube driver has 12 buttons and 6 axes
717- 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 ));
717+ SDL_strlcat (mapping_string , "a:b0,b:b2 ,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:b1 ,y:b3,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1 ," , sizeof (mapping_string ));
718718 } else if (vendor == USB_VENDOR_NINTENDO &&
719719 (guid .data [15 ] == k_eSwitchDeviceInfoControllerType_HVCLeft ||
720720 guid .data [15 ] == k_eSwitchDeviceInfoControllerType_HVCRight ||
@@ -781,7 +781,11 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
781781 }
782782 } else {
783783 // All other gamepads have the standard set of 19 buttons and 6 axes
784- 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 ));
784+ if (SDL_IsJoystickGameCube (vendor , product )) {
785+ SDL_strlcat (mapping_string , "a:b0,b:b2,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:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1," , sizeof (mapping_string ));
786+ } else {
787+ 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 ));
788+ }
785789
786790 if (SDL_IsJoystickSteamController (vendor , product )) {
787791 // Steam controllers have 2 back paddle buttons
@@ -1110,7 +1114,7 @@ SDL_COMPILE_TIME_ASSERT(map_StringForGamepadButton, SDL_arraysize(map_StringForG
11101114/*
11111115 * convert a string to its enum equivalent
11121116 */
1113- static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString (const char * str , bool baxy )
1117+ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString (const char * str , bool axby , bool baxy )
11141118{
11151119 int i ;
11161120
@@ -1120,7 +1124,17 @@ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString(const char *str,
11201124
11211125 for (i = 0 ; i < SDL_arraysize (map_StringForGamepadButton ); ++ i ) {
11221126 if (SDL_strcasecmp (str , map_StringForGamepadButton [i ]) == 0 ) {
1123- if (baxy ) {
1127+ if (axby ) {
1128+ // Need to swap face buttons
1129+ switch (i ) {
1130+ case SDL_GAMEPAD_BUTTON_EAST :
1131+ return SDL_GAMEPAD_BUTTON_WEST ;
1132+ case SDL_GAMEPAD_BUTTON_WEST :
1133+ return SDL_GAMEPAD_BUTTON_EAST ;
1134+ default :
1135+ break ;
1136+ }
1137+ } else if (baxy ) {
11241138 // Need to swap face buttons
11251139 switch (i ) {
11261140 case SDL_GAMEPAD_BUTTON_SOUTH :
@@ -1142,7 +1156,7 @@ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString(const char *str,
11421156}
11431157SDL_GamepadButton SDL_GetGamepadButtonFromString (const char * str )
11441158{
1145- return SDL_PrivateGetGamepadButtonFromString (str , false);
1159+ return SDL_PrivateGetGamepadButtonFromString (str , false, false );
11461160}
11471161
11481162/*
@@ -1169,6 +1183,7 @@ static bool SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szG
11691183 char half_axis_output = 0 ;
11701184 int i ;
11711185 SDL_GamepadBinding * new_bindings ;
1186+ bool axby_mapping = false;
11721187 bool baxy_mapping = false;
11731188
11741189 SDL_AssertJoysticksLocked ();
@@ -1179,12 +1194,17 @@ static bool SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szG
11791194 half_axis_output = * szGameButton ++ ;
11801195 }
11811196
1197+ if (SDL_strstr (gamepad -> mapping -> mapping , ",hint:SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1" ) != NULL ) {
1198+ axby_mapping = true;
1199+ }
11821200 if (SDL_strstr (gamepad -> mapping -> mapping , ",hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1" ) != NULL ) {
11831201 baxy_mapping = true;
11841202 }
1203+ // FIXME: We fix these up when loading the mapping, does this ever get hit?
1204+ //SDL_assert(!axby_mapping && !baxy_mapping);
11851205
11861206 axis = SDL_GetGamepadAxisFromString (szGameButton );
1187- button = SDL_PrivateGetGamepadButtonFromString (szGameButton , baxy_mapping );
1207+ button = SDL_PrivateGetGamepadButtonFromString (szGameButton , axby_mapping , baxy_mapping );
11881208 if (axis != SDL_GAMEPAD_AXIS_INVALID ) {
11891209 bind .output_type = SDL_GAMEPAD_BINDTYPE_AXIS ;
11901210 bind .output .axis .axis = axis ;
@@ -1401,6 +1421,11 @@ static void SDL_UpdateGamepadFaceStyle(SDL_Gamepad *gamepad)
14011421 }
14021422 }
14031423
1424+ if (gamepad -> face_style == SDL_GAMEPAD_FACE_STYLE_UNKNOWN &&
1425+ SDL_strstr (gamepad -> mapping -> mapping , "SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS" ) != NULL ) {
1426+ // This controller uses GameCube button style
1427+ gamepad -> face_style = SDL_GAMEPAD_FACE_STYLE_AXBY ;
1428+ }
14041429 if (gamepad -> face_style == SDL_GAMEPAD_FACE_STYLE_UNKNOWN &&
14051430 SDL_strstr (gamepad -> mapping -> mapping , "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" ) != NULL ) {
14061431 // This controller uses Nintendo button style
@@ -1466,24 +1491,6 @@ static void SDL_FixupHIDAPIMapping(SDL_Gamepad *gamepad)
14661491 }
14671492}
14681493
1469- static void SDL_FixupGameCubeMapping (SDL_Gamepad * gamepad , const char * pchString )
1470- {
1471- if (SDL_strstr (gamepad -> mapping -> mapping , SDL_GAMEPAD_FACE_FIELD ) != NULL ) {
1472- return ;
1473- }
1474-
1475- for (int i = 0 ; i < gamepad -> num_bindings ; ++ i ) {
1476- SDL_GamepadBinding * binding = & gamepad -> bindings [i ];
1477- if (binding -> output_type == SDL_GAMEPAD_BINDTYPE_BUTTON ) {
1478- if (binding -> output .button == SDL_GAMEPAD_BUTTON_EAST ) {
1479- binding -> output .button = SDL_GAMEPAD_BUTTON_WEST ;
1480- } else if (binding -> output .button == SDL_GAMEPAD_BUTTON_WEST ) {
1481- binding -> output .button = SDL_GAMEPAD_BUTTON_EAST ;
1482- }
1483- }
1484- }
1485- }
1486-
14871494/*
14881495 * Make a new button mapping struct
14891496 */
@@ -1509,10 +1516,6 @@ static void SDL_PrivateLoadButtonMapping(SDL_Gamepad *gamepad, GamepadMapping_t
15091516 SDL_FixupHIDAPIMapping (gamepad );
15101517 }
15111518
1512- if (SDL_IsJoystickGameCube (SDL_GetGamepadVendor (gamepad ), SDL_GetGamepadProduct (gamepad ))) {
1513- SDL_FixupGameCubeMapping (gamepad , pGamepadMapping -> mapping );
1514- }
1515-
15161519 // Set the zero point for triggers
15171520 for (i = 0 ; i < gamepad -> num_bindings ; ++ i ) {
15181521 SDL_GamepadBinding * binding = & gamepad -> bindings [i ];
@@ -1983,7 +1986,37 @@ bool SDL_ReloadGamepadMappings(void)
19831986 return true;
19841987}
19851988
1986- static char * SDL_ConvertMappingToPositional (const char * mapping )
1989+ static char * SDL_ConvertMappingToPositionalAXBY (const char * mapping )
1990+ {
1991+ // Add space for '!' and null terminator
1992+ size_t length = SDL_strlen (mapping ) + 1 + 1 ;
1993+ char * remapped = (char * )SDL_malloc (length );
1994+ if (remapped ) {
1995+ char * button_B ;
1996+ char * button_X ;
1997+ char * hint ;
1998+
1999+ SDL_strlcpy (remapped , mapping , length );
2000+ button_B = SDL_strstr (remapped , ",b:" );
2001+ button_X = SDL_strstr (remapped , ",x:" );
2002+ hint = SDL_strstr (remapped , "hint:SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS" );
2003+
2004+ if (button_B ) {
2005+ button_B [1 ] = 'x' ;
2006+ }
2007+ if (button_X ) {
2008+ button_X [1 ] = 'b' ;
2009+ }
2010+ if (hint ) {
2011+ hint += 5 ;
2012+ SDL_memmove (hint + 1 , hint , SDL_strlen (hint ) + 1 );
2013+ * hint = '!' ;
2014+ }
2015+ }
2016+ return remapped ;
2017+ }
2018+
2019+ static char * SDL_ConvertMappingToPositionalBAXY (const char * mapping )
19872020{
19882021 // Add space for '!' and null terminator
19892022 size_t length = SDL_strlen (mapping ) + 1 + 1 ;
@@ -1996,23 +2029,23 @@ static char *SDL_ConvertMappingToPositional(const char *mapping)
19962029 char * hint ;
19972030
19982031 SDL_strlcpy (remapped , mapping , length );
1999- button_A = SDL_strstr (remapped , "a:" );
2000- button_B = SDL_strstr (remapped , "b:" );
2001- button_X = SDL_strstr (remapped , "x:" );
2002- button_Y = SDL_strstr (remapped , "y:" );
2032+ button_A = SDL_strstr (remapped , ", a:" );
2033+ button_B = SDL_strstr (remapped , ", b:" );
2034+ button_X = SDL_strstr (remapped , ", x:" );
2035+ button_Y = SDL_strstr (remapped , ", y:" );
20032036 hint = SDL_strstr (remapped , "hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS" );
20042037
20052038 if (button_A ) {
2006- * button_A = 'b' ;
2039+ button_A [ 1 ] = 'b' ;
20072040 }
20082041 if (button_B ) {
2009- * button_B = 'a' ;
2042+ button_B [ 1 ] = 'a' ;
20102043 }
20112044 if (button_X ) {
2012- * button_X = 'y' ;
2045+ button_X [ 1 ] = 'y' ;
20132046 }
20142047 if (button_Y ) {
2015- * button_Y = 'x' ;
2048+ button_Y [ 1 ] = 'x' ;
20162049 }
20172050 if (hint ) {
20182051 hint += 5 ;
@@ -2028,9 +2061,11 @@ static char *SDL_ConvertMappingToPositional(const char *mapping)
20282061 */
20292062static int SDL_PrivateAddGamepadMapping (const char * mappingString , SDL_GamepadMappingPriority priority )
20302063{
2064+ char * appended = NULL ;
20312065 char * remapped = NULL ;
20322066 char * pchGUID ;
2033- SDL_GUID jGUID ;
2067+ SDL_GUID guid ;
2068+ Uint16 vendor , product ;
20342069 bool is_default_mapping = false;
20352070 bool is_xinput_mapping = false;
20362071 bool existing = false;
@@ -2044,6 +2079,28 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
20442079 return -1 ;
20452080 }
20462081
2082+ pchGUID = SDL_PrivateGetGamepadGUIDFromMappingString (mappingString );
2083+ if (!pchGUID ) {
2084+ SDL_SetError ("Couldn't parse GUID from %s" , mappingString );
2085+ return -1 ;
2086+ }
2087+ if (!SDL_strcasecmp (pchGUID , "default" )) {
2088+ is_default_mapping = true;
2089+ } else if (!SDL_strcasecmp (pchGUID , "xinput" )) {
2090+ is_xinput_mapping = true;
2091+ }
2092+ guid = SDL_StringToGUID (pchGUID );
2093+ SDL_free (pchGUID );
2094+
2095+ SDL_GetJoystickGUIDInfo (guid , & vendor , & product , NULL , NULL );
2096+ if (SDL_IsJoystickGameCube (vendor , product ) &&
2097+ SDL_strstr (mappingString , "SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS" ) == NULL ) {
2098+ SDL_asprintf (& appended , "%shint:SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1," , mappingString );
2099+ if (appended ) {
2100+ mappingString = appended ;
2101+ }
2102+ }
2103+
20472104 { // Extract and verify the hint field
20482105 const char * tmp ;
20492106
@@ -2075,18 +2132,31 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
20752132 default_value = false;
20762133 }
20772134
2078- if (SDL_strcmp (hint , "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" ) == 0 ) {
2135+ if (SDL_strcmp (hint , "SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS" ) == 0 ) {
2136+ // This hint is used to signal whether the mapping uses positional buttons or not
2137+ if (negate ) {
2138+ // This mapping uses positional buttons, we can use it as-is
2139+ } else {
2140+ // This mapping uses labeled buttons, we need to swap them to positional
2141+ remapped = SDL_ConvertMappingToPositionalAXBY (mappingString );
2142+ if (!remapped ) {
2143+ goto done ;
2144+ }
2145+ mappingString = remapped ;
2146+ }
2147+ } else if (SDL_strcmp (hint , "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" ) == 0 ) {
20792148 // This hint is used to signal whether the mapping uses positional buttons or not
20802149 if (negate ) {
20812150 // This mapping uses positional buttons, we can use it as-is
20822151 } else {
20832152 // This mapping uses labeled buttons, we need to swap them to positional
2084- remapped = SDL_ConvertMappingToPositional (mappingString );
2153+ remapped = SDL_ConvertMappingToPositionalBAXY (mappingString );
20852154 if (!remapped ) {
20862155 goto done ;
20872156 }
20882157 mappingString = remapped ;
20892158 }
2159+
20902160 } else {
20912161 value = SDL_GetHintBoolean (hint , default_value );
20922162 if (negate ) {
@@ -2123,20 +2193,7 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
21232193 }
21242194#endif
21252195
2126- pchGUID = SDL_PrivateGetGamepadGUIDFromMappingString (mappingString );
2127- if (!pchGUID ) {
2128- SDL_SetError ("Couldn't parse GUID from %s" , mappingString );
2129- goto done ;
2130- }
2131- if (!SDL_strcasecmp (pchGUID , "default" )) {
2132- is_default_mapping = true;
2133- } else if (!SDL_strcasecmp (pchGUID , "xinput" )) {
2134- is_xinput_mapping = true;
2135- }
2136- jGUID = SDL_StringToGUID (pchGUID );
2137- SDL_free (pchGUID );
2138-
2139- pGamepadMapping = SDL_PrivateAddMappingForGUID (jGUID , mappingString , & existing , priority );
2196+ pGamepadMapping = SDL_PrivateAddMappingForGUID (guid , mappingString , & existing , priority );
21402197 if (!pGamepadMapping ) {
21412198 goto done ;
21422199 }
@@ -2152,9 +2209,8 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
21522209 result = 1 ;
21532210 }
21542211done :
2155- if (remapped ) {
2156- SDL_free (remapped );
2157- }
2212+ SDL_free (appended );
2213+ SDL_free (remapped );
21582214 return result ;
21592215}
21602216
0 commit comments