@@ -714,7 +714,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
714
714
product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 ||
715
715
product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3 ))) {
716
716
// 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 ));
718
718
} else if (vendor == USB_VENDOR_NINTENDO &&
719
719
(guid .data [15 ] == k_eSwitchDeviceInfoControllerType_HVCLeft ||
720
720
guid .data [15 ] == k_eSwitchDeviceInfoControllerType_HVCRight ||
@@ -781,7 +781,11 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
781
781
}
782
782
} else {
783
783
// 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
+ }
785
789
786
790
if (SDL_IsJoystickSteamController (vendor , product )) {
787
791
// Steam controllers have 2 back paddle buttons
@@ -1110,7 +1114,7 @@ SDL_COMPILE_TIME_ASSERT(map_StringForGamepadButton, SDL_arraysize(map_StringForG
1110
1114
/*
1111
1115
* convert a string to its enum equivalent
1112
1116
*/
1113
- static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString (const char * str , bool baxy )
1117
+ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString (const char * str , bool axby , bool baxy )
1114
1118
{
1115
1119
int i ;
1116
1120
@@ -1120,7 +1124,17 @@ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString(const char *str,
1120
1124
1121
1125
for (i = 0 ; i < SDL_arraysize (map_StringForGamepadButton ); ++ i ) {
1122
1126
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 ) {
1124
1138
// Need to swap face buttons
1125
1139
switch (i ) {
1126
1140
case SDL_GAMEPAD_BUTTON_SOUTH :
@@ -1142,7 +1156,7 @@ static SDL_GamepadButton SDL_PrivateGetGamepadButtonFromString(const char *str,
1142
1156
}
1143
1157
SDL_GamepadButton SDL_GetGamepadButtonFromString (const char * str )
1144
1158
{
1145
- return SDL_PrivateGetGamepadButtonFromString (str , false);
1159
+ return SDL_PrivateGetGamepadButtonFromString (str , false, false );
1146
1160
}
1147
1161
1148
1162
/*
@@ -1169,6 +1183,7 @@ static bool SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szG
1169
1183
char half_axis_output = 0 ;
1170
1184
int i ;
1171
1185
SDL_GamepadBinding * new_bindings ;
1186
+ bool axby_mapping = false;
1172
1187
bool baxy_mapping = false;
1173
1188
1174
1189
SDL_AssertJoysticksLocked ();
@@ -1179,12 +1194,17 @@ static bool SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szG
1179
1194
half_axis_output = * szGameButton ++ ;
1180
1195
}
1181
1196
1197
+ if (SDL_strstr (gamepad -> mapping -> mapping , ",hint:SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1" ) != NULL ) {
1198
+ axby_mapping = true;
1199
+ }
1182
1200
if (SDL_strstr (gamepad -> mapping -> mapping , ",hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1" ) != NULL ) {
1183
1201
baxy_mapping = true;
1184
1202
}
1203
+ // FIXME: We fix these up when loading the mapping, does this ever get hit?
1204
+ //SDL_assert(!axby_mapping && !baxy_mapping);
1185
1205
1186
1206
axis = SDL_GetGamepadAxisFromString (szGameButton );
1187
- button = SDL_PrivateGetGamepadButtonFromString (szGameButton , baxy_mapping );
1207
+ button = SDL_PrivateGetGamepadButtonFromString (szGameButton , axby_mapping , baxy_mapping );
1188
1208
if (axis != SDL_GAMEPAD_AXIS_INVALID ) {
1189
1209
bind .output_type = SDL_GAMEPAD_BINDTYPE_AXIS ;
1190
1210
bind .output .axis .axis = axis ;
@@ -1401,6 +1421,11 @@ static void SDL_UpdateGamepadFaceStyle(SDL_Gamepad *gamepad)
1401
1421
}
1402
1422
}
1403
1423
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
+ }
1404
1429
if (gamepad -> face_style == SDL_GAMEPAD_FACE_STYLE_UNKNOWN &&
1405
1430
SDL_strstr (gamepad -> mapping -> mapping , "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" ) != NULL ) {
1406
1431
// This controller uses Nintendo button style
@@ -1466,24 +1491,6 @@ static void SDL_FixupHIDAPIMapping(SDL_Gamepad *gamepad)
1466
1491
}
1467
1492
}
1468
1493
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
-
1487
1494
/*
1488
1495
* Make a new button mapping struct
1489
1496
*/
@@ -1509,10 +1516,6 @@ static void SDL_PrivateLoadButtonMapping(SDL_Gamepad *gamepad, GamepadMapping_t
1509
1516
SDL_FixupHIDAPIMapping (gamepad );
1510
1517
}
1511
1518
1512
- if (SDL_IsJoystickGameCube (SDL_GetGamepadVendor (gamepad ), SDL_GetGamepadProduct (gamepad ))) {
1513
- SDL_FixupGameCubeMapping (gamepad , pGamepadMapping -> mapping );
1514
- }
1515
-
1516
1519
// Set the zero point for triggers
1517
1520
for (i = 0 ; i < gamepad -> num_bindings ; ++ i ) {
1518
1521
SDL_GamepadBinding * binding = & gamepad -> bindings [i ];
@@ -1983,7 +1986,37 @@ bool SDL_ReloadGamepadMappings(void)
1983
1986
return true;
1984
1987
}
1985
1988
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 )
1987
2020
{
1988
2021
// Add space for '!' and null terminator
1989
2022
size_t length = SDL_strlen (mapping ) + 1 + 1 ;
@@ -1996,23 +2029,23 @@ static char *SDL_ConvertMappingToPositional(const char *mapping)
1996
2029
char * hint ;
1997
2030
1998
2031
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:" );
2003
2036
hint = SDL_strstr (remapped , "hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS" );
2004
2037
2005
2038
if (button_A ) {
2006
- * button_A = 'b' ;
2039
+ button_A [ 1 ] = 'b' ;
2007
2040
}
2008
2041
if (button_B ) {
2009
- * button_B = 'a' ;
2042
+ button_B [ 1 ] = 'a' ;
2010
2043
}
2011
2044
if (button_X ) {
2012
- * button_X = 'y' ;
2045
+ button_X [ 1 ] = 'y' ;
2013
2046
}
2014
2047
if (button_Y ) {
2015
- * button_Y = 'x' ;
2048
+ button_Y [ 1 ] = 'x' ;
2016
2049
}
2017
2050
if (hint ) {
2018
2051
hint += 5 ;
@@ -2028,9 +2061,11 @@ static char *SDL_ConvertMappingToPositional(const char *mapping)
2028
2061
*/
2029
2062
static int SDL_PrivateAddGamepadMapping (const char * mappingString , SDL_GamepadMappingPriority priority )
2030
2063
{
2064
+ char * appended = NULL ;
2031
2065
char * remapped = NULL ;
2032
2066
char * pchGUID ;
2033
- SDL_GUID jGUID ;
2067
+ SDL_GUID guid ;
2068
+ Uint16 vendor , product ;
2034
2069
bool is_default_mapping = false;
2035
2070
bool is_xinput_mapping = false;
2036
2071
bool existing = false;
@@ -2044,6 +2079,28 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
2044
2079
return -1 ;
2045
2080
}
2046
2081
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
+
2047
2104
{ // Extract and verify the hint field
2048
2105
const char * tmp ;
2049
2106
@@ -2075,18 +2132,31 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
2075
2132
default_value = false;
2076
2133
}
2077
2134
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 ) {
2079
2148
// This hint is used to signal whether the mapping uses positional buttons or not
2080
2149
if (negate ) {
2081
2150
// This mapping uses positional buttons, we can use it as-is
2082
2151
} else {
2083
2152
// This mapping uses labeled buttons, we need to swap them to positional
2084
- remapped = SDL_ConvertMappingToPositional (mappingString );
2153
+ remapped = SDL_ConvertMappingToPositionalBAXY (mappingString );
2085
2154
if (!remapped ) {
2086
2155
goto done ;
2087
2156
}
2088
2157
mappingString = remapped ;
2089
2158
}
2159
+
2090
2160
} else {
2091
2161
value = SDL_GetHintBoolean (hint , default_value );
2092
2162
if (negate ) {
@@ -2123,20 +2193,7 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
2123
2193
}
2124
2194
#endif
2125
2195
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 );
2140
2197
if (!pGamepadMapping ) {
2141
2198
goto done ;
2142
2199
}
@@ -2152,9 +2209,8 @@ static int SDL_PrivateAddGamepadMapping(const char *mappingString, SDL_GamepadMa
2152
2209
result = 1 ;
2153
2210
}
2154
2211
done :
2155
- if (remapped ) {
2156
- SDL_free (remapped );
2157
- }
2212
+ SDL_free (appended );
2213
+ SDL_free (remapped );
2158
2214
return result ;
2159
2215
}
2160
2216
0 commit comments