Skip to content

Commit 31650d5

Browse files
committed
Added SDL_GAMEPAD_TYPE_GAMECUBE
The GameCube controller has a different face button layout than the Xbox or Nintendo Switch style controllers. It has the B button on the left and the X button on the right, so we should map those to SDL_GAMEPAD_BUTTON_WEST with SDL_GAMEPAD_BUTTON_LABEL_B and SDL_GAMEPAD_BUTTON_EAST with SDL_GAMEPAD_BUTTON_LABEL_X respectively. Fixes #12847
1 parent c4d5cc3 commit 31650d5

File tree

10 files changed

+2841
-32
lines changed

10 files changed

+2841
-32
lines changed

include/SDL3/SDL_gamepad.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ typedef enum SDL_GamepadType
118118
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT,
119119
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT,
120120
SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR,
121+
SDL_GAMEPAD_TYPE_GAMECUBE,
121122
SDL_GAMEPAD_TYPE_COUNT
122123
} SDL_GamepadType;
123124

@@ -127,8 +128,8 @@ typedef enum SDL_GamepadType
127128
* For controllers that use a diamond pattern for the face buttons, the
128129
* south/east/west/north buttons below correspond to the locations in the
129130
* diamond pattern. For Xbox controllers, this would be A/B/X/Y, for Nintendo
130-
* Switch controllers, this would be B/A/Y/X, for PlayStation controllers this
131-
* would be Cross/Circle/Square/Triangle.
131+
* Switch controllers, this would be B/A/Y/X, for GameCube controllers this
132+
* would be A/X/B/Y, for PlayStation controllers this would be Cross/Circle/Square/Triangle.
132133
*
133134
* For controllers that don't use a diamond pattern for the face buttons, the
134135
* south/east/west/north buttons indicate the buttons labeled A, B, C, D, or

src/joystick/SDL_gamepad.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef enum
6262
{
6363
SDL_GAMEPAD_FACE_STYLE_UNKNOWN,
6464
SDL_GAMEPAD_FACE_STYLE_ABXY,
65+
SDL_GAMEPAD_FACE_STYLE_AXBY,
6566
SDL_GAMEPAD_FACE_STYLE_BAYX,
6667
SDL_GAMEPAD_FACE_STYLE_SONY,
6768
} SDL_GamepadFaceStyle;
@@ -710,7 +711,8 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
710711
if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) ||
711712
(vendor == USB_VENDOR_DRAGONRISE &&
712713
(product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 ||
713-
product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2))) {
714+
product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 ||
715+
product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3))) {
714716
// GameCube driver has 12 buttons and 6 axes
715717
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));
716718
} else if (vendor == USB_VENDOR_NINTENDO &&
@@ -992,7 +994,8 @@ static const char *map_StringForGamepadType[] = {
992994
"switchpro",
993995
"joyconleft",
994996
"joyconright",
995-
"joyconpair"
997+
"joyconpair",
998+
"gamecube"
996999
};
9971000
SDL_COMPILE_TIME_ASSERT(map_StringForGamepadType, SDL_arraysize(map_StringForGamepadType) == SDL_GAMEPAD_TYPE_COUNT);
9981001

@@ -1347,6 +1350,8 @@ static SDL_GamepadFaceStyle SDL_GetGamepadFaceStyleFromString(const char *string
13471350
{
13481351
if (SDL_strcmp(string, "abxy") == 0) {
13491352
return SDL_GAMEPAD_FACE_STYLE_ABXY;
1353+
} else if (SDL_strcmp(string, "axby") == 0) {
1354+
return SDL_GAMEPAD_FACE_STYLE_AXBY;
13501355
} else if (SDL_strcmp(string, "bayx") == 0) {
13511356
return SDL_GAMEPAD_FACE_STYLE_BAYX;
13521357
} else if (SDL_strcmp(string, "sony") == 0) {
@@ -1368,6 +1373,8 @@ static SDL_GamepadFaceStyle SDL_GetGamepadFaceStyleForGamepadType(SDL_GamepadTyp
13681373
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT:
13691374
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
13701375
return SDL_GAMEPAD_FACE_STYLE_BAYX;
1376+
case SDL_GAMEPAD_TYPE_GAMECUBE:
1377+
return SDL_GAMEPAD_FACE_STYLE_AXBY;
13711378
default:
13721379
return SDL_GAMEPAD_FACE_STYLE_ABXY;
13731380
}
@@ -2997,6 +3004,24 @@ static SDL_GamepadButtonLabel SDL_GetGamepadButtonLabelForFaceStyle(SDL_GamepadF
29973004
break;
29983005
}
29993006
break;
3007+
case SDL_GAMEPAD_FACE_STYLE_AXBY:
3008+
switch (button) {
3009+
case SDL_GAMEPAD_BUTTON_SOUTH:
3010+
label = SDL_GAMEPAD_BUTTON_LABEL_A;
3011+
break;
3012+
case SDL_GAMEPAD_BUTTON_EAST:
3013+
label = SDL_GAMEPAD_BUTTON_LABEL_X;
3014+
break;
3015+
case SDL_GAMEPAD_BUTTON_WEST:
3016+
label = SDL_GAMEPAD_BUTTON_LABEL_B;
3017+
break;
3018+
case SDL_GAMEPAD_BUTTON_NORTH:
3019+
label = SDL_GAMEPAD_BUTTON_LABEL_Y;
3020+
break;
3021+
default:
3022+
break;
3023+
}
3024+
break;
30003025
case SDL_GAMEPAD_FACE_STYLE_BAYX:
30013026
switch (button) {
30023027
case SDL_GAMEPAD_BUTTON_SOUTH:

src/joystick/SDL_gamepad_db.h

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

src/joystick/SDL_joystick.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,13 @@ static SDL_vidpid_list flightstick_devices = {
479479
};
480480

481481
static Uint32 initial_gamecube_devices[] = {
482+
MAKE_VIDPID(0x0079, 0x1843), // DragonRise GameCube Controller Adapter
483+
MAKE_VIDPID(0x0079, 0x1844), // DragonRise GameCube Controller Adapter
484+
MAKE_VIDPID(0x0079, 0x1846), // DragonRise GameCube Controller Adapter
485+
MAKE_VIDPID(0x057e, 0x0337), // Nintendo Wii U GameCube Controller Adapter
486+
MAKE_VIDPID(0x0926, 0x8888), // Cyber Gadget GameCube Controller
482487
MAKE_VIDPID(0x0e6f, 0x0185), // PDP Wired Fight Pad Pro for Nintendo Switch
488+
MAKE_VIDPID(0x1a34, 0xf705), // GameCube {HuiJia USB box}
483489
MAKE_VIDPID(0x20d6, 0xa711), // PowerA Wired Controller Nintendo GameCube Style
484490
};
485491
static SDL_vidpid_list gamecube_devices = {
@@ -2937,8 +2943,7 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
29372943
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR;
29382944

29392945
} else if (forUI && SDL_IsJoystickGameCube(vendor, product)) {
2940-
// We don't have a type for the Nintendo GameCube controller
2941-
type = SDL_GAMEPAD_TYPE_STANDARD;
2946+
type = SDL_GAMEPAD_TYPE_GAMECUBE;
29422947

29432948
} else {
29442949
switch (GuessControllerType(vendor, product)) {

src/joystick/hidapi/SDL_hidapi_gamecube.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ static bool HIDAPI_DriverGameCube_IsSupportedDevice(SDL_HIDAPI_Device *device, c
7474
}
7575
if (vendor_id == USB_VENDOR_DRAGONRISE &&
7676
(product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 ||
77-
product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2)) {
77+
product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 ||
78+
product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3)) {
7879
// EVORETRO GameCube Controller Adapter
7980
return true;
8081
}
@@ -232,10 +233,10 @@ static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device
232233
joystick, \
233234
button, \
234235
((packet[off] & flag) != 0));
235-
READ_BUTTON(1, 0x02, 0) // A
236-
READ_BUTTON(1, 0x04, 1) // B
237-
READ_BUTTON(1, 0x08, 3) // Y
238-
READ_BUTTON(1, 0x01, 2) // X
236+
READ_BUTTON(1, 0x02, 0) // SOUTH (A)
237+
READ_BUTTON(1, 0x01, 1) // EAST (X)
238+
READ_BUTTON(1, 0x04, 2) // WEST (B)
239+
READ_BUTTON(1, 0x08, 3) // NORTH (Y)
239240
READ_BUTTON(2, 0x80, 4) // DPAD_LEFT
240241
READ_BUTTON(2, 0x20, 5) // DPAD_RIGHT
241242
READ_BUTTON(2, 0x40, 6) // DPAD_DOWN

src/joystick/hidapi/SDL_hidapi_switch.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ typedef struct
285285
SDL_HIDAPI_Device *device;
286286
SDL_Joystick *joystick;
287287
bool m_bInputOnly;
288+
bool m_bGameCube;
288289
bool m_bUseButtonLabels;
289290
bool m_bPlayerLights;
290291
int m_nPlayerIndex;
@@ -1130,7 +1131,20 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
11301131

11311132
static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
11321133
{
1133-
if (ctx->m_bUseButtonLabels) {
1134+
if (ctx->m_bGameCube) {
1135+
switch (button) {
1136+
case SDL_GAMEPAD_BUTTON_SOUTH:
1137+
return SDL_GAMEPAD_BUTTON_WEST;
1138+
case SDL_GAMEPAD_BUTTON_EAST:
1139+
return SDL_GAMEPAD_BUTTON_SOUTH;
1140+
case SDL_GAMEPAD_BUTTON_WEST:
1141+
return SDL_GAMEPAD_BUTTON_NORTH;
1142+
case SDL_GAMEPAD_BUTTON_NORTH:
1143+
return SDL_GAMEPAD_BUTTON_EAST;
1144+
default:
1145+
break;
1146+
}
1147+
} else if (ctx->m_bUseButtonLabels) {
11341148
// Use button labels instead of positions, e.g. Nintendo Online Classic controllers
11351149
switch (button) {
11361150
case SDL_GAMEPAD_BUTTON_SOUTH:
@@ -1232,9 +1246,6 @@ static bool HasHomeLED(SDL_DriverSwitch_Context *ctx)
12321246
static bool AlwaysUsesLabels(Uint16 vendor_id, Uint16 product_id, ESwitchDeviceInfoControllerType eControllerType)
12331247
{
12341248
// Some controllers don't have a diamond button configuration, so should always use labels
1235-
if (SDL_IsJoystickGameCube(vendor_id, product_id)) {
1236-
return true;
1237-
}
12381249
switch (eControllerType) {
12391250
case k_eSwitchDeviceInfoControllerType_HVCLeft:
12401251
case k_eSwitchDeviceInfoControllerType_HVCRight:
@@ -1367,7 +1378,7 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
13671378

13681379
if (ctx->m_bInputOnly) {
13691380
if (SDL_IsJoystickGameCube(device->vendor_id, device->product_id)) {
1370-
device->type = SDL_GAMEPAD_TYPE_STANDARD;
1381+
device->type = SDL_GAMEPAD_TYPE_GAMECUBE;
13711382
}
13721383
} else {
13731384
char serial[18];
@@ -1590,7 +1601,9 @@ static bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joys
15901601
}
15911602
}
15921603

1593-
if (AlwaysUsesLabels(device->vendor_id, device->product_id, ctx->m_eControllerType)) {
1604+
if (SDL_IsJoystickGameCube(device->vendor_id, device->product_id)) {
1605+
ctx->m_bGameCube = true;
1606+
} else if (AlwaysUsesLabels(device->vendor_id, device->product_id, ctx->m_eControllerType)) {
15941607
ctx->m_bUseButtonLabels = true;
15951608
}
15961609

src/joystick/usb_ids.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
#define USB_PRODUCT_BACKBONE_ONE_IOS_PS5 0x0104
6767
#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400
6868
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 0x1843
69-
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 0x1846
69+
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 0x1844
70+
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER3 0x1846
7071
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS4 0x011c
7172
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184
7273
#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184

test/gamepad_face_axby.bmp

32.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)