From 90191458215f4b8d626ff91268dcec164d0d7ecb Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Fri, 25 Jul 2025 12:38:22 -0400 Subject: [PATCH 01/33] Initial Button Prompt detection support for now: this only applies to Key Bindings menu --- port/include/glyph.h | 21 ++++ port/include/input.h | 19 ++++ port/src/glyph.c | 245 +++++++++++++++++++++++++++++++++++++++++ port/src/input.c | 92 ++++++++++++++++ port/src/optionsmenu.c | 42 ++++++- 5 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 port/include/glyph.h create mode 100644 port/src/glyph.c diff --git a/port/include/glyph.h b/port/include/glyph.h new file mode 100644 index 0000000000..a7abca75b5 --- /dev/null +++ b/port/include/glyph.h @@ -0,0 +1,21 @@ +#ifndef _IN_GLYPH_H +#define _IN_GLYPH_H + +// Controller Icon enumeration for button icon detection +typedef enum { + CONTROLLER_ICON_GENERIC, + CONTROLLER_ICON_XBOX360, + CONTROLLER_ICON_XBOXONE, + CONTROLLER_ICON_PS3, + CONTROLLER_ICON_PS4, + CONTROLLER_ICON_PS5, + CONTROLLER_ICON_NINTENDO_SWITCH, +} ControllerIconType; + +// Generic display names for controller buttons +extern const char *vkJoyDisplayNames[]; + +// Function to get controller-specific button name with fallback to generic +const char *glyphGetButtonName(int controllerType, int buttonIndex); + +#endif \ No newline at end of file diff --git a/port/include/input.h b/port/include/input.h index 6171c26961..489bc20413 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -121,6 +121,18 @@ enum mouselockmode { MLOCK_AUTO = 2 }; +enum buttonpromptmode { + GLYPH_AUTO = 0, + GLYPH_GENERIC = 1, + GLYPH_INTERNAL = 2, + GLYPH_XBOX360 = 3, + GLYPH_XBOXONE = 4, + GLYPH_PS3 = 5, + GLYPH_PS4 = 6, + GLYPH_PS5 = 7, + GLYPH_NINTENDO_SWITCH = 8 +}; + // returns bitmask of connected controllers or -1 if failed s32 inputInit(void); @@ -193,6 +205,9 @@ s32 inputGetKeyByName(const char *name); // get human-readable name from VK_ value const char *inputGetKeyName(s32 vk); +// get human-readable controller button display name from VK_ value +const char *inputGetButtonDisplayName(s32 vk); + // get CK_ value from human-readable name s32 inputGetContKeyByName(const char *name); @@ -249,6 +264,10 @@ s32 inputGetLastKey(void); s32 inputGetMouseLockMode(void); void inputSetMouseLockMode(s32 lockmode); +// get/set button prompt override +s32 inputGetButtonPromptOverride(s32 cidx); +void inputSetButtonPromptOverride(s32 cidx, s32 override); + // same as inputLockMouse but works only if mouse is enabled and lockmode == MLOCK_AUTO s32 inputAutoLockMouse(s32 wantlock); diff --git a/port/src/glyph.c b/port/src/glyph.c new file mode 100644 index 0000000000..0099f8370b --- /dev/null +++ b/port/src/glyph.c @@ -0,0 +1,245 @@ +#include +#include "glyph.h" + +// Generic display names for controller buttons (maps to same indices as vkJoyNames) +const char *vkJoyDisplayNames[] = { + "BTN_SOUTH", // A button (Bottom face button) + "BTN_EAST", // B button (Right face button) + "BTN_WEST", // X button (Left face button) + "BTN_NORTH", // Y button (Top face button) + "BTN_BACK", + "BTN_GUIDE", + "BTN_START", + "STICK_LEFT_CLICK", + "STICK_RIGHT_CLICK", + "SHOULDER_LEFT", + "SHOULDER_RIGHT", + "D-PAD_UP", + "D-PAD_DOWN", + "D-PAD_LEFT", + "D-PAD_RIGHT", + "BTN_MISC1", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) + "RIGHT_PADDLE_1", // Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) + "LEFT_PADDLE_1", // Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) + "RIGHT_PADDLE_2", // Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) + "LEFT_PADDLE_2", // Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) + "BTN_TOUCHPAD", // PS4/PS5 touchpad button + "BTN_MISC2", + "BTN_MISC3", + "BTN_MISC4", + "BTN_MISC5", + "BTN_MISC6", + "BTN_26", + "BTN_27", + "BTN_28", + "BTN_29", + "LEFT_TRIG", + "RIGHT_TRIG", +}; + +// Controller-specific overrides + +// Common Xbox controller button overrides +static const struct { + int button_index; + const char *name; +} xbox_prompts[] = { + { 0, "BTN_A" }, + { 1, "BTN_B" }, + { 2, "BTN_X" }, + { 3, "BTN_Y" }, + { 5, "BTN_XBOX"}, +}; + +// Xbox 360 specific button overrides +static const struct { + int button_index; + const char *name; +} xbox360_overrides[] = { + { 4, "BTN_BACK" }, + { 6, "BTN_START" }, +}; + +// Xbox One specific button overrides +static const struct { + int button_index; + const char *name; +} xboxone_overrides[] = { + { 4, "BTN_VIEW" }, + { 6, "BTN_MENU" }, + { 15, "BTN_SHARE" }, + { 16, "BTN_PADDLE1" }, // Xbox Elite right upper paddle + { 17, "BTN_PADDLE2" }, // Xbox Elite left upper paddle + { 18, "BTN_PADDLE3" }, // Xbox Elite right lower paddle + { 19, "BTN_PADDLE4" }, // Xbox Elite left lower paddle +}; + +// Common PlayStation controller button overrides +static const struct { + int button_index; + const char *name; +} playstation_prompts[] = { + { 0, "BTN_CROSS" }, + { 1, "BTN_CIRCLE" }, + { 2, "BTN_SQUARE" }, + { 3, "BTN_TRIANGLE" }, + { 5, "BTN_PS" }, + { 7, "STICK_L3" }, + { 8, "STICK_R3" }, + { 9, "BTN_L1" }, + { 10, "BTN_R1" }, + { 30, "TRIG_L2" }, + { 31, "TRIG_R2" }, +}; + +// PS3 specific button overrides +static const struct { + int button_index; + const char *name; +} ps3_overrides[] = { + { 4, "BTN_SELECT" }, + { 6, "BTN_START" }, +}; + +// PS4 specific button overrides +static const struct { + int button_index; + const char *name; +} ps4_overrides[] = { + { 4, "BTN_SHARE" }, + { 6, "BTN_OPTIONS" }, +}; + +// PS5 specific button overrides +static const struct { + int button_index; + const char *name; +} ps5_overrides[] = { + { 4, "BTN_CREATE" }, + { 6, "BTN_OPTIONS" }, + { 15, "BTN_MIC" }, // PS5 microphone mute button + { 18, "BTN_LB" }, // DualSense Edge left back button + { 19, "BTN_RB" }, // DualSense Edge right back button +}; + +// Nintendo Switch controller button overrides +static const struct { + int button_index; + const char *name; +} switch_overrides[] = { + { 0, "BTN_B" }, // Nintendo layout + { 1, "BTN_A" }, // Nintendo layout + { 2, "BTN_Y" }, // Nintendo layout + { 3, "BTN_X" }, // Nintendo layout + { 4, "BTN_MINUS" }, + { 5, "BTN_HOME" }, + { 6, "BTN_PLUS" }, + { 9, "BTN_L" }, + { 10, "BTN_R" }, + { 15, "BTN_CAPTURE" }, + { 16, "BTN_SL" }, + { 17, "BTN_SR" }, + { 30, "TRIG_ZL" }, + { 31, "TRIG_ZR" }, +}; + +// Function to get controller-specific button name with fallback to generic +const char *glyphGetButtonName(int controllerType, int buttonIndex) +{ + switch (controllerType) { + case CONTROLLER_ICON_XBOX360: + // Check Xbox 360 specific overrides first + for (int i = 0; i < sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]); i++) { + if (xbox360_overrides[i].button_index == buttonIndex) { + return xbox360_overrides[i].name; + } + } + // Fallback to common Xbox overrides + for (int i = 0; i < sizeof(xbox_prompts) / sizeof(xbox_prompts[0]); i++) { + if (xbox_prompts[i].button_index == buttonIndex) { + return xbox_prompts[i].name; + } + } + break; + + case CONTROLLER_ICON_XBOXONE: + // Check Xbox One specific overrides first + for (int i = 0; i < sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]); i++) { + if (xboxone_overrides[i].button_index == buttonIndex) { + return xboxone_overrides[i].name; + } + } + // Fallback to common Xbox overrides + for (int i = 0; i < sizeof(xbox_prompts) / sizeof(xbox_prompts[0]); i++) { + if (xbox_prompts[i].button_index == buttonIndex) { + return xbox_prompts[i].name; + } + } + break; + + case CONTROLLER_ICON_PS3: + // Check PS3 specific overrides first + for (int i = 0; i < sizeof(ps3_overrides) / sizeof(ps3_overrides[0]); i++) { + if (ps3_overrides[i].button_index == buttonIndex) { + return ps3_overrides[i].name; + } + } + // Fallback to common PlayStation overrides + for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { + if (playstation_prompts[i].button_index == buttonIndex) { + return playstation_prompts[i].name; + } + } + break; + + case CONTROLLER_ICON_PS4: + // Check PS4 specific overrides first + for (int i = 0; i < sizeof(ps4_overrides) / sizeof(ps4_overrides[0]); i++) { + if (ps4_overrides[i].button_index == buttonIndex) { + return ps4_overrides[i].name; + } + } + // Fallback to common PlayStation overrides + for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { + if (playstation_prompts[i].button_index == buttonIndex) { + return playstation_prompts[i].name; + } + } + break; + + case CONTROLLER_ICON_PS5: + // Check PS5 specific overrides first + for (int i = 0; i < sizeof(ps5_overrides) / sizeof(ps5_overrides[0]); i++) { + if (ps5_overrides[i].button_index == buttonIndex) { + return ps5_overrides[i].name; + } + } + // Fallback to common PlayStation overrides + for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { + if (playstation_prompts[i].button_index == buttonIndex) { + return playstation_prompts[i].name; + } + } + break; + + case CONTROLLER_ICON_NINTENDO_SWITCH: + for (int i = 0; i < sizeof(switch_overrides) / sizeof(switch_overrides[0]); i++) { + if (switch_overrides[i].button_index == buttonIndex) { + return switch_overrides[i].name; + } + } + break; + + case CONTROLLER_ICON_GENERIC: // Generic/fallback + default: + break; + } + + // Fallback to generic names if no override found or unknown controller type + if (buttonIndex >= 0 && buttonIndex < 32) { + return vkJoyDisplayNames[buttonIndex]; + } + + return "UNKNOWN BUTTON"; +} + diff --git a/port/src/input.c b/port/src/input.c index 41e0fa0387..1aec1d15e3 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -11,6 +11,7 @@ #include "utils.h" #include "system.h" #include "fs.h" +#include "glyph.h" #if !SDL_VERSION_ATLEAST(2, 0, 14) // this was added in 2.0.14 @@ -46,6 +47,7 @@ static SDL_GameController *pads[INPUT_MAX_CONTROLLERS]; .swapSticks = 1, \ .deviceIndex = -1, \ .cancelCButtons = 0, \ + .buttonPromptOverride = 0, \ } static struct controllercfg { @@ -58,6 +60,7 @@ static struct controllercfg { s32 swapSticks; s32 deviceIndex; s32 cancelCButtons; + s32 buttonPromptOverride; } padsCfg[INPUT_MAX_CONTROLLERS] = { CONTROLLERCFG_DEFAULT, CONTROLLERCFG_DEFAULT, @@ -693,6 +696,7 @@ s32 inputInit(void) // the two hints below enable Rumble and Motion Sensor for PS4/5 pads connected via bluetooth SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAM, "1"); #endif #if SDL_VERSION_ATLEAST(2, 23, 2) SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, "1"); @@ -702,6 +706,9 @@ s32 inputInit(void) #endif #if SDL_VERSION_ATLEAST(2, 26, 0) SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_WII, "1"); +#endif +#if SDL_VERSION_ATLEAST(2, 30, 0) + SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, "1"); #endif } if (useRawInput) { @@ -1319,6 +1326,22 @@ void inputSetMouseLockMode(s32 lockmode) } } +s32 inputGetButtonPromptOverride(s32 cidx) +{ + if (cidx < 0 || cidx >= INPUT_MAX_CONTROLLERS) { + return 0; // Default to GLYPH_AUTO + } + return padsCfg[cidx].buttonPromptOverride; +} + +void inputSetButtonPromptOverride(s32 cidx, s32 override) +{ + if (cidx < 0 || cidx >= INPUT_MAX_CONTROLLERS) { + return; + } + padsCfg[cidx].buttonPromptOverride = override; +} + const char *inputGetContKeyName(u32 ck) { if (ck >= CK_TOTAL_COUNT) { @@ -1349,6 +1372,74 @@ const char *inputGetKeyName(s32 vk) return vkNames[vk]; } +const char *inputGetButtonDisplayName(s32 vk) +{ + if (vk < 0 || vk >= VK_TOTAL_COUNT) { + return inputGetKeyName(vk); + } + + if (vk >= VK_JOY_BEGIN && vk < VK_TOTAL_COUNT) { + const u32 cidx = (vk - VK_JOY_BEGIN) / INPUT_MAX_CONTROLLER_BUTTONS; + const u32 jbtn = (vk - VK_JOY_BEGIN) % INPUT_MAX_CONTROLLER_BUTTONS; + + if (jbtn < INPUT_MAX_CONTROLLER_BUTTONS) { + const s32 override = (cidx < INPUT_MAX_CONTROLLERS) ? padsCfg[cidx].buttonPromptOverride : GLYPH_AUTO; + + if (override == GLYPH_AUTO) { + if (cidx < INPUT_MAX_CONTROLLERS && pads[cidx]) { + const SDL_GameControllerType type = SDL_GameControllerGetType(pads[cidx]); + + switch (type) { + case SDL_CONTROLLER_TYPE_XBOX360: + return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + case SDL_CONTROLLER_TYPE_XBOXONE: + return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + case SDL_CONTROLLER_TYPE_PS3: + return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + case SDL_CONTROLLER_TYPE_PS4: + return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); +#if SDL_VERSION_ATLEAST(2, 0, 14) + case SDL_CONTROLLER_TYPE_PS5: + return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); +#endif + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: +#if SDL_VERSION_ATLEAST(2, 24, 0) +#if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: +#endif +#if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: +#endif +#if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR) + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: +#endif +#endif + return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + case SDL_CONTROLLER_TYPE_UNKNOWN: + default: + return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + } + } + return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + } else if (override == GLYPH_INTERNAL) { + if (jbtn < sizeof(vkJoyNames) / sizeof(vkJoyNames[0])) { + static char playerButtonName[64]; + const char *baseName = vkJoyNames[jbtn]; + snprintf(playerButtonName, sizeof(playerButtonName), "JOY%d_%s", + (int)(cidx + 1), baseName + 5); + return playerButtonName; + } + return inputGetKeyName(vk); + } else { + const ControllerIconType iconType = (ControllerIconType)(override - 1); + return glyphGetButtonName(iconType, jbtn); + } + } + } + + return inputGetKeyName(vk); +} + s32 inputGetKeyByName(const char *name) { s32 start = 0; @@ -1532,6 +1623,7 @@ PD_CONSTRUCTOR static void inputConfigInit(void) configRegisterInt(strFmt("%s.CancelCButtons", secname), &padsCfg[c].cancelCButtons, 0, 1); configRegisterInt(strFmt("%s.SwapSticks", secname), &padsCfg[c].swapSticks, 0, 1); configRegisterInt(strFmt("%s.ControllerIndex", secname), &padsCfg[c].deviceIndex, -1, 0x7FFFFFFF); + configRegisterInt(strFmt("%s.ButtonPromptOverride", secname), &padsCfg[c].buttonPromptOverride, GLYPH_AUTO, GLYPH_NINTENDO_SWITCH); secname[13] = '.'; for (u32 ck = 0; ck < CK_TOTAL_COUNT; ++ck) { snprintf(keyname, sizeof(keyname), "%s.%s", secname, inputGetContKeyName(ck)); diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 5632153346..64ad836493 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -14,6 +14,7 @@ #include "video.h" #include "input.h" #include "config.h" +#include "glyph.h" static s32 g_ExtMenuPlayer = 0; static struct menudialogdef *g_ExtNextDialog = NULL; @@ -616,6 +617,37 @@ static MenuItemHandlerResult menuhandlerController(s32 operation, struct menuite return 0; } +static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, struct menuitem *item, union handlerdata *data) +{ + static const char *opts[] = { + "Auto", + "Generic", + "Internal", + "Xbox 360 Controller", + "Xbox Wireless Controller", + "DualShock 3", + "DualShock 4", + "DualSense", + "Nintendo Switch Controller" + }; + + switch (operation) { + case MENUOP_GETOPTIONCOUNT: + data->dropdown.value = ARRAYCOUNT(opts); + break; + case MENUOP_GETOPTIONTEXT: + return (intptr_t)opts[data->dropdown.value]; + case MENUOP_SET: + inputSetButtonPromptOverride(g_ExtMenuPlayer, data->dropdown.value); + break; + case MENUOP_GETSELECTEDINDEX: + data->dropdown.value = inputGetButtonPromptOverride(g_ExtMenuPlayer); + break; + } + + return 0; +} + struct menuitem g_ExtendedControllerMenuItems[] = { { MENUITEMTYPE_DROPDOWN, @@ -625,6 +657,14 @@ struct menuitem g_ExtendedControllerMenuItems[] = { 0, menuhandlerController, }, + { + MENUITEMTYPE_DROPDOWN, + 0, + MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"Button Icons", + 0, + menuhandlerButtonPromptOverride, + }, { MENUITEMTYPE_CHECKBOX, 0, @@ -1771,7 +1811,7 @@ static MenuItemHandlerResult menuhandlerBind(s32 operation, struct menuitem *ite case MENUOP_GETOPTIONTEXT: binds = inputKeyGetBinds(g_ExtMenuPlayer, menuBinds[idx].ck); if (binds && binds[data->dropdown.value]) { - strncpy(keyname, inputGetKeyName(binds[data->dropdown.value]), sizeof(keyname) - 1); + strncpy(keyname, inputGetButtonDisplayName(binds[data->dropdown.value]), sizeof(keyname) - 1); for (char *p = keyname; *p; ++p) { if (*p == '_') *p = ' '; } From 51204c74e3efe0855ecf72970f29c3c4797c6fbb Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Fri, 25 Jul 2025 12:41:21 -0400 Subject: [PATCH 02/33] rename "button icons" with "button prompt styles" since this repository doesn't do Button Icons, the name has been changed to properly the text-based Button Prompt "icons". --- port/src/optionsmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 64ad836493..26d644ce1a 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -661,7 +661,7 @@ struct menuitem g_ExtendedControllerMenuItems[] = { MENUITEMTYPE_DROPDOWN, 0, MENUITEMFLAG_LITERAL_TEXT, - (uintptr_t)"Button Icons", + (uintptr_t)"Button Prompt Styles", 0, menuhandlerButtonPromptOverride, }, From a85ba0512cf46d07dd7dfd411b35de5be34e7f32 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:14:55 -0400 Subject: [PATCH 03/33] updated Glyph naming scheme to closely follow device button layout --- port/src/glyph.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 0099f8370b..0efc9f0d6a 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -18,17 +18,17 @@ const char *vkJoyDisplayNames[] = { "D-PAD_DOWN", "D-PAD_LEFT", "D-PAD_RIGHT", - "BTN_MISC1", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) + "BTN_MISC_1", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) "RIGHT_PADDLE_1", // Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) "LEFT_PADDLE_1", // Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) "RIGHT_PADDLE_2", // Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) "LEFT_PADDLE_2", // Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) "BTN_TOUCHPAD", // PS4/PS5 touchpad button - "BTN_MISC2", - "BTN_MISC3", - "BTN_MISC4", - "BTN_MISC5", - "BTN_MISC6", + "BTN_MISC_2", + "BTN_MISC_3", + "BTN_MISC_4", + "BTN_MISC_5", + "BTN_MISC_6", "BTN_26", "BTN_27", "BTN_28", @@ -49,6 +49,8 @@ static const struct { { 2, "BTN_X" }, { 3, "BTN_Y" }, { 5, "BTN_XBOX"}, + { 9, "SHOULDER_LB" }, + { 10, "SHOULDER_RB" }, }; // Xbox 360 specific button overrides @@ -68,10 +70,10 @@ static const struct { { 4, "BTN_VIEW" }, { 6, "BTN_MENU" }, { 15, "BTN_SHARE" }, - { 16, "BTN_PADDLE1" }, // Xbox Elite right upper paddle - { 17, "BTN_PADDLE2" }, // Xbox Elite left upper paddle - { 18, "BTN_PADDLE3" }, // Xbox Elite right lower paddle - { 19, "BTN_PADDLE4" }, // Xbox Elite left lower paddle + { 16, "PADDLE_1" }, // Xbox Elite right upper paddle + { 17, "PADDLE_2" }, // Xbox Elite left upper paddle + { 18, "PADDLE_3" }, // Xbox Elite right lower paddle + { 19, "PADDLE_4" }, // Xbox Elite left lower paddle }; // Common PlayStation controller button overrides @@ -86,8 +88,8 @@ static const struct { { 5, "BTN_PS" }, { 7, "STICK_L3" }, { 8, "STICK_R3" }, - { 9, "BTN_L1" }, - { 10, "BTN_R1" }, + { 9, "SHOULDER_L1" }, + { 10, "SHOULDER_R1" }, { 30, "TRIG_L2" }, { 31, "TRIG_R2" }, }; @@ -118,8 +120,8 @@ static const struct { { 4, "BTN_CREATE" }, { 6, "BTN_OPTIONS" }, { 15, "BTN_MIC" }, // PS5 microphone mute button - { 18, "BTN_LB" }, // DualSense Edge left back button - { 19, "BTN_RB" }, // DualSense Edge right back button + { 18, "PADDLE_LB" }, // DualSense Edge left back button + { 19, "PADDLE_RB" }, // DualSense Edge right back button }; // Nintendo Switch controller button overrides @@ -127,15 +129,15 @@ static const struct { int button_index; const char *name; } switch_overrides[] = { - { 0, "BTN_B" }, // Nintendo layout - { 1, "BTN_A" }, // Nintendo layout - { 2, "BTN_Y" }, // Nintendo layout - { 3, "BTN_X" }, // Nintendo layout + { 0, "BTN_B" }, // Nintendo layout, A button (Bottom face button) + { 1, "BTN_A" }, // Nintendo layout, B button (Right face button) + { 2, "BTN_Y" }, // Nintendo layout, X button (Left face button) + { 3, "BTN_X" }, // Nintendo layout, Y button (Top face button) { 4, "BTN_MINUS" }, { 5, "BTN_HOME" }, { 6, "BTN_PLUS" }, - { 9, "BTN_L" }, - { 10, "BTN_R" }, + { 9, "SHOULDER_L" }, + { 10, "SHOULDER_R" }, { 15, "BTN_CAPTURE" }, { 16, "BTN_SL" }, { 17, "BTN_SR" }, From aa7dcf2cffba1b784ad2854546f725c944944cfb Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:51:45 -0400 Subject: [PATCH 04/33] changed Xbox Elite Paddle naming scheme to mirror device name --- port/src/glyph.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 0efc9f0d6a..ea80b7d985 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -70,10 +70,10 @@ static const struct { { 4, "BTN_VIEW" }, { 6, "BTN_MENU" }, { 15, "BTN_SHARE" }, - { 16, "PADDLE_1" }, // Xbox Elite right upper paddle - { 17, "PADDLE_2" }, // Xbox Elite left upper paddle - { 18, "PADDLE_3" }, // Xbox Elite right lower paddle - { 19, "PADDLE_4" }, // Xbox Elite left lower paddle + { 16, "PADDLE_P1" }, // Xbox Elite right upper paddle + { 17, "PADDLE_P2" }, // Xbox Elite left upper paddle + { 18, "PADDLE_P3" }, // Xbox Elite right lower paddle + { 19, "PADDLE_P4" }, // Xbox Elite left lower paddle }; // Common PlayStation controller button overrides From cc5b7dfe1213c05ed7ae83fcac8b280a4cee9675 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Sun, 27 Jul 2025 22:17:44 -0400 Subject: [PATCH 05/33] change glyph order --- port/include/input.h | 18 +++++++++--------- port/src/input.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/port/include/input.h b/port/include/input.h index 489bc20413..f58eed783a 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -122,15 +122,15 @@ enum mouselockmode { }; enum buttonpromptmode { - GLYPH_AUTO = 0, - GLYPH_GENERIC = 1, - GLYPH_INTERNAL = 2, - GLYPH_XBOX360 = 3, - GLYPH_XBOXONE = 4, - GLYPH_PS3 = 5, - GLYPH_PS4 = 6, - GLYPH_PS5 = 7, - GLYPH_NINTENDO_SWITCH = 8 + GLYPH_AUTO = -1, + GLYPH_GENERIC = 0, + GLYPH_INTERNAL = 1, + GLYPH_XBOX360 = 2, + GLYPH_XBOXONE = 3, + GLYPH_PS3 = 4, + GLYPH_PS4 = 5, + GLYPH_PS5 = 6, + GLYPH_NINTENDO_SWITCH = 7 }; // returns bitmask of connected controllers or -1 if failed diff --git a/port/src/input.c b/port/src/input.c index 1aec1d15e3..7e441c1096 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -47,7 +47,7 @@ static SDL_GameController *pads[INPUT_MAX_CONTROLLERS]; .swapSticks = 1, \ .deviceIndex = -1, \ .cancelCButtons = 0, \ - .buttonPromptOverride = 0, \ + .buttonPromptOverride = -1, \ } static struct controllercfg { From 8f9c13a219c34455f1a37db9745efcc54485b6c0 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Sun, 27 Jul 2025 22:32:13 -0400 Subject: [PATCH 06/33] fixed Button Prompt override order DualSense prompt accidentally uses Nintendo Switch prompts. This has be addressed. --- port/src/optionsmenu.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 26d644ce1a..185655b3be 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -619,29 +619,43 @@ static MenuItemHandlerResult menuhandlerController(s32 operation, struct menuite static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, struct menuitem *item, union handlerdata *data) { - static const char *opts[] = { - "Auto", - "Generic", - "Internal", - "Xbox 360 Controller", - "Xbox Wireless Controller", - "DualShock 3", - "DualShock 4", - "DualSense", - "Nintendo Switch Controller" + static const struct { + const char *name; + s32 value; + } promptOptions[] = { + { "Auto", GLYPH_AUTO }, + { "Generic", GLYPH_GENERIC }, + { "Internal", GLYPH_INTERNAL }, + { "Xbox 360 Controller", GLYPH_XBOX360 }, + { "Xbox Wireless Controller", GLYPH_XBOXONE }, + { "DualShock 3", GLYPH_PS3 }, + { "DualShock 4", GLYPH_PS4 }, + { "DualSense", GLYPH_PS5 }, + { "Nintendo Switch Controller", GLYPH_NINTENDO_SWITCH } }; switch (operation) { case MENUOP_GETOPTIONCOUNT: - data->dropdown.value = ARRAYCOUNT(opts); + data->dropdown.value = ARRAYCOUNT(promptOptions); break; case MENUOP_GETOPTIONTEXT: - return (intptr_t)opts[data->dropdown.value]; + return (intptr_t)promptOptions[data->dropdown.value].name; case MENUOP_SET: - inputSetButtonPromptOverride(g_ExtMenuPlayer, data->dropdown.value); + if (data->dropdown.value >= 0 && data->dropdown.value < ARRAYCOUNT(promptOptions)) { + inputSetButtonPromptOverride(g_ExtMenuPlayer, promptOptions[data->dropdown.value].value); + } break; case MENUOP_GETSELECTEDINDEX: - data->dropdown.value = inputGetButtonPromptOverride(g_ExtMenuPlayer); + { + s32 currentValue = inputGetButtonPromptOverride(g_ExtMenuPlayer); + for (s32 i = 0; i < ARRAYCOUNT(promptOptions); i++) { + if (promptOptions[i].value == currentValue) { + data->dropdown.value = i; + return 0; + } + } + data->dropdown.value = 0; + } break; } From ebc22077d3699370888cc12c315503cc459d08c0 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 28 Jul 2025 17:16:58 -0400 Subject: [PATCH 07/33] Modularized `glyph.c` setup instead of hardcoding (aside from Nintendo Switch's), there's now a standardization setup that can be used across all Controller Types if needed. --- port/src/glyph.c | 338 ++++++++++++++++++++++++----------------------- 1 file changed, 170 insertions(+), 168 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index ea80b7d985..7c6234c095 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -3,32 +3,32 @@ // Generic display names for controller buttons (maps to same indices as vkJoyNames) const char *vkJoyDisplayNames[] = { - "BTN_SOUTH", // A button (Bottom face button) - "BTN_EAST", // B button (Right face button) - "BTN_WEST", // X button (Left face button) - "BTN_NORTH", // Y button (Top face button) - "BTN_BACK", - "BTN_GUIDE", - "BTN_START", - "STICK_LEFT_CLICK", - "STICK_RIGHT_CLICK", - "SHOULDER_LEFT", - "SHOULDER_RIGHT", + "SOUTH_BTN", // A button (Bottom face button) + "EAST_BTN", // B button (Right face button) + "WEST_BTN", // X button (Left face button) + "NORTH_BTN", // Y button (Top face button) + "BACK_BTN", + "GUIDE_BTN", + "START_BTN", + "LEFT_STICK_CLICK", + "RIGHT_STICK_CLICK", + "LEFT_SHOULDER", + "RIGHT_SHOULDER", "D-PAD_UP", "D-PAD_DOWN", "D-PAD_LEFT", "D-PAD_RIGHT", - "BTN_MISC_1", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) + "MISC1_BTN", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) "RIGHT_PADDLE_1", // Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) "LEFT_PADDLE_1", // Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) "RIGHT_PADDLE_2", // Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) "LEFT_PADDLE_2", // Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) - "BTN_TOUCHPAD", // PS4/PS5 touchpad button - "BTN_MISC_2", - "BTN_MISC_3", - "BTN_MISC_4", - "BTN_MISC_5", - "BTN_MISC_6", + "TOUCHPAD_BTN", // PS4/PS5 touchpad button + "MISC2_BTN", + "MISC3_BTN", + "MISC4_BTN", + "MISC5_BTN", + "MISC6_BTN", "BTN_26", "BTN_27", "BTN_28", @@ -39,209 +39,211 @@ const char *vkJoyDisplayNames[] = { // Controller-specific overrides -// Common Xbox controller button overrides -static const struct { +// Common struct type for button overrides +struct button_override { int button_index; const char *name; -} xbox_prompts[] = { - { 0, "BTN_A" }, - { 1, "BTN_B" }, - { 2, "BTN_X" }, - { 3, "BTN_Y" }, - { 5, "BTN_XBOX"}, - { 9, "SHOULDER_LB" }, - { 10, "SHOULDER_RB" }, +}; + +// Standard button overrides (shared across controllers) +static const struct button_override glyph_standard[] = { + { 0, "A_BTN" }, // Bottom face button (A) + { 1, "B_BTN" }, // Right face button (B) + { 2, "X_BTN" }, // Left face button (X) + { 3, "Y_BTN" }, // Top face button (Y) + { 7, "L3_STICK_CLICK" }, // Left stick press (L3) + { 8, "R3_STICK_CLICK" }, // Right stick press (R3) + { 9, "L1_SHOULDER" }, // Left shoulder (L1) + { 10, "R1_SHOULDER" }, // Right shoulder (R1) + { 15, "M1_BTN" }, // M1 button (MISC 1) + { 16, "L4_BTN" }, // Left paddle (L4) + { 17, "L5_BTN" }, // Left paddle (L5) + { 18, "R4_BTN" }, // Right paddle (R4) + { 19, "R5_BTN" }, // Right paddle (R5) + { 21, "M2_BTN" }, // M2 button (MISC 2) + { 22, "M3_BTN" }, // M3 button (MISC 3) + { 23, "M4_BTN" }, // M4 button (MISC 4) + { 30, "L2_TRIG" }, // Left trigger (L2) + { 31, "R2_TRIG" }, // Right trigger (R2) +}; + +// Xbox-specific overrides +static const struct button_override xbox_specific[] = { + { 5, "XBOX_BTN" }, + { 9, "LB_SHOULDER" }, + { 10, "RB_SHOULDER" }, + { 30, "LT_TRIG" }, + { 31, "RT_TRIG" }, }; // Xbox 360 specific button overrides -static const struct { - int button_index; - const char *name; -} xbox360_overrides[] = { - { 4, "BTN_BACK" }, - { 6, "BTN_START" }, +static const struct button_override xbox360_overrides[] = { + { 4, "BACK_BTN" }, + { 6, "START_BTN" }, }; -// Xbox One specific button overrides -static const struct { - int button_index; - const char *name; -} xboxone_overrides[] = { - { 4, "BTN_VIEW" }, - { 6, "BTN_MENU" }, - { 15, "BTN_SHARE" }, - { 16, "PADDLE_P1" }, // Xbox Elite right upper paddle - { 17, "PADDLE_P2" }, // Xbox Elite left upper paddle - { 18, "PADDLE_P3" }, // Xbox Elite right lower paddle - { 19, "PADDLE_P4" }, // Xbox Elite left lower paddle +// Xbox One/Series X|S-specific button overrides +static const struct button_override xboxone_overrides[] = { + { 4, "VIEW_BTN" }, + { 6, "MENU_BTN" }, + { 15, "SHARE_BTN" }, + { 16, "PADDLE_1" }, // Xbox Elite right upper paddle + { 17, "PADDLE_2" }, // Xbox Elite left upper paddle + { 18, "PADDLE_3" }, // Xbox Elite right lower paddle + { 19, "PADDLE_4" }, // Xbox Elite left lower paddle }; -// Common PlayStation controller button overrides -static const struct { - int button_index; - const char *name; -} playstation_prompts[] = { - { 0, "BTN_CROSS" }, - { 1, "BTN_CIRCLE" }, - { 2, "BTN_SQUARE" }, - { 3, "BTN_TRIANGLE" }, - { 5, "BTN_PS" }, - { 7, "STICK_L3" }, - { 8, "STICK_R3" }, - { 9, "SHOULDER_L1" }, - { 10, "SHOULDER_R1" }, - { 30, "TRIG_L2" }, - { 31, "TRIG_R2" }, +// PlayStation-specific overrides +static const struct button_override playstation_specific[] = { + { 0, "CROSS_BTN" }, + { 1, "CIRCLE_BTN" }, + { 2, "SQUARE_BTN" }, + { 3, "TRIANGLE_BTN" }, + { 5, "PS_BTN" }, + { 20, "TOUCHPAD_BTN" }, }; -// PS3 specific button overrides -static const struct { - int button_index; - const char *name; -} ps3_overrides[] = { - { 4, "BTN_SELECT" }, - { 6, "BTN_START" }, +// PS3-specific button overrides +static const struct button_override ps3_overrides[] = { + { 4, "SELECT_BTN" }, + { 6, "START_BTN" }, }; -// PS4 specific button overrides -static const struct { - int button_index; - const char *name; -} ps4_overrides[] = { - { 4, "BTN_SHARE" }, - { 6, "BTN_OPTIONS" }, +// PS4-specific button overrides +static const struct button_override ps4_overrides[] = { + { 4, "SHARE_BTN" }, + { 6, "OPTIONS_BTN" }, }; -// PS5 specific button overrides -static const struct { - int button_index; - const char *name; -} ps5_overrides[] = { - { 4, "BTN_CREATE" }, - { 6, "BTN_OPTIONS" }, - { 15, "BTN_MIC" }, // PS5 microphone mute button - { 18, "PADDLE_LB" }, // DualSense Edge left back button - { 19, "PADDLE_RB" }, // DualSense Edge right back button +// PS5-specific button overrides +static const struct button_override ps5_overrides[] = { + { 4, "CREATE_BTN" }, + { 6, "OPTIONS_BTN" }, + { 15, "MIC_BTN" }, // PS5 microphone mute button + { 18, "LB_PADDLE" }, // DualSense Edge left back button + { 19, "RB_PADDLE" }, // DualSense Edge right back button }; -// Nintendo Switch controller button overrides -static const struct { - int button_index; - const char *name; -} switch_overrides[] = { - { 0, "BTN_B" }, // Nintendo layout, A button (Bottom face button) - { 1, "BTN_A" }, // Nintendo layout, B button (Right face button) - { 2, "BTN_Y" }, // Nintendo layout, X button (Left face button) - { 3, "BTN_X" }, // Nintendo layout, Y button (Top face button) - { 4, "BTN_MINUS" }, - { 5, "BTN_HOME" }, - { 6, "BTN_PLUS" }, - { 9, "SHOULDER_L" }, - { 10, "SHOULDER_R" }, - { 15, "BTN_CAPTURE" }, - { 16, "BTN_SL" }, - { 17, "BTN_SR" }, - { 30, "TRIG_ZL" }, - { 31, "TRIG_ZR" }, +// Nintendo Switch-specific overrides +static const struct button_override switch_specific[] = { + { 0, "B_BTN" }, // Nintendo bottom button → "B" equivalent + { 1, "A_BTN" }, // Nintendo right button → "A" equivalent + { 2, "Y_BTN" }, // Nintendo left button → "Y" equivalent + { 3, "X_BTN" }, // Nintendo top button → "X" equivalent + { 4, "MINUS_BTN" }, + { 5, "HOME_BTN" }, + { 6, "PLUS_BTN" }, + { 9, "L_SHOULDER" }, + { 10, "R_SHOULDER" }, + { 15, "CAPTURE_BTN" }, + { 16, "SL_BTN" }, + { 17, "SR_BTN" }, + { 30, "ZL_TRIG" }, + { 31, "ZR_TRIG" }, }; +// Helper function to search an override array +static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { + for (int i = 0; i < count; i++) { + if (overrides[i].button_index == buttonIndex) { + return overrides[i].name; + } + } + return NULL; +} + // Function to get controller-specific button name with fallback to generic const char *glyphGetButtonName(int controllerType, int buttonIndex) { + const char *result = NULL; + switch (controllerType) { case CONTROLLER_ICON_XBOX360: - // Check Xbox 360 specific overrides first - for (int i = 0; i < sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]); i++) { - if (xbox360_overrides[i].button_index == buttonIndex) { - return xbox360_overrides[i].name; - } - } - // Fallback to common Xbox overrides - for (int i = 0; i < sizeof(xbox_prompts) / sizeof(xbox_prompts[0]); i++) { - if (xbox_prompts[i].button_index == buttonIndex) { - return xbox_prompts[i].name; - } + // Xbox 360-specific overrides + result = searchOverrides(xbox360_overrides, sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]), buttonIndex); + if (result) return result; + // 2. Xbox overrides + result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + if (result) return result; + // 3. Glyph standard (Face Button only) + if (buttonIndex >= 0 && buttonIndex <= 3) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; } break; case CONTROLLER_ICON_XBOXONE: - // Check Xbox One specific overrides first - for (int i = 0; i < sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]); i++) { - if (xboxone_overrides[i].button_index == buttonIndex) { - return xboxone_overrides[i].name; - } - } - // Fallback to common Xbox overrides - for (int i = 0; i < sizeof(xbox_prompts) / sizeof(xbox_prompts[0]); i++) { - if (xbox_prompts[i].button_index == buttonIndex) { - return xbox_prompts[i].name; - } + // 1. Xbox One/Series X|S-specific overrides + result = searchOverrides(xboxone_overrides, sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]), buttonIndex); + if (result) return result; + // 2. Xbox overrides + result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + if (result) return result; + // 3. Glyph standard (Face Button only) + if (buttonIndex >= 0 && buttonIndex <= 3) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; } break; case CONTROLLER_ICON_PS3: - // Check PS3 specific overrides first - for (int i = 0; i < sizeof(ps3_overrides) / sizeof(ps3_overrides[0]); i++) { - if (ps3_overrides[i].button_index == buttonIndex) { - return ps3_overrides[i].name; - } - } - // Fallback to common PlayStation overrides - for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { - if (playstation_prompts[i].button_index == buttonIndex) { - return playstation_prompts[i].name; - } + // PS3-specific overrides + result = searchOverrides(ps3_overrides, sizeof(ps3_overrides) / sizeof(ps3_overrides[0]), buttonIndex); + if (result) return result; + // 2. PlayStation overrides + result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + if (result) return result; + // 3. Glyph standard (Face, Shoulders, Triggers only) + if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; } break; case CONTROLLER_ICON_PS4: - // Check PS4 specific overrides first - for (int i = 0; i < sizeof(ps4_overrides) / sizeof(ps4_overrides[0]); i++) { - if (ps4_overrides[i].button_index == buttonIndex) { - return ps4_overrides[i].name; - } - } - // Fallback to common PlayStation overrides - for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { - if (playstation_prompts[i].button_index == buttonIndex) { - return playstation_prompts[i].name; - } + // 1. PS4-specific overrides + result = searchOverrides(ps4_overrides, sizeof(ps4_overrides) / sizeof(ps4_overrides[0]), buttonIndex); + if (result) return result; + // 2. PlayStation overrides + result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + if (result) return result; + // 3. Glyph standard (Face, Shoulders, Triggers only) + if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; } break; case CONTROLLER_ICON_PS5: - // Check PS5 specific overrides first - for (int i = 0; i < sizeof(ps5_overrides) / sizeof(ps5_overrides[0]); i++) { - if (ps5_overrides[i].button_index == buttonIndex) { - return ps5_overrides[i].name; - } - } - // Fallback to common PlayStation overrides - for (int i = 0; i < sizeof(playstation_prompts) / sizeof(playstation_prompts[0]); i++) { - if (playstation_prompts[i].button_index == buttonIndex) { - return playstation_prompts[i].name; - } + // 1. PS5-specific overrides + result = searchOverrides(ps5_overrides, sizeof(ps5_overrides) / sizeof(ps5_overrides[0]), buttonIndex); + if (result) return result; + // 2. PlayStation overrides + result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + if (result) return result; + // 3. Glyph standard (Face, Shoulders, Triggers only) + if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; } break; case CONTROLLER_ICON_NINTENDO_SWITCH: - for (int i = 0; i < sizeof(switch_overrides) / sizeof(switch_overrides[0]); i++) { - if (switch_overrides[i].button_index == buttonIndex) { - return switch_overrides[i].name; - } - } + // 1. Nintendo Switch specific overrides + result = searchOverrides(switch_specific, sizeof(switch_specific) / sizeof(switch_specific[0]), buttonIndex); + if (result) return result; + // 2. Glyph standard (will fallback to generic prompts going forward) break; - case CONTROLLER_ICON_GENERIC: // Generic/fallback + case CONTROLLER_ICON_GENERIC: default: break; } - // Fallback to generic names if no override found or unknown controller type + // Final fallback to generic names if (buttonIndex >= 0 && buttonIndex < 32) { return vkJoyDisplayNames[buttonIndex]; } return "UNKNOWN BUTTON"; } - From 8535f87c95fdd6a89aff6b6c9f50e1a9186ccf0a Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 28 Jul 2025 17:18:02 -0400 Subject: [PATCH 08/33] cleaned up `inputGetButtonDisplayName` --- port/src/glyph.c | 32 +++++++------- port/src/input.c | 99 ++++++++++++++++++++++-------------------- port/src/optionsmenu.c | 14 +++--- 3 files changed, 73 insertions(+), 72 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 7c6234c095..a7df407735 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -142,7 +142,7 @@ static const struct button_override switch_specific[] = { { 31, "ZR_TRIG" }, }; -// Helper function to search an override array +// Helper function to search an override a specific button index static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { for (int i = 0; i < count; i++) { if (overrides[i].button_index == buttonIndex) { @@ -162,10 +162,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // Xbox 360-specific overrides result = searchOverrides(xbox360_overrides, sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]), buttonIndex); if (result) return result; - // 2. Xbox overrides + // Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face Button only) + // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -173,13 +173,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_XBOXONE: - // 1. Xbox One/Series X|S-specific overrides + // Xbox One/Series X|S-specific overrides result = searchOverrides(xboxone_overrides, sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]), buttonIndex); if (result) return result; - // 2. Xbox overrides + // Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face Button only) + // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -190,10 +190,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // PS3-specific overrides result = searchOverrides(ps3_overrides, sizeof(ps3_overrides) / sizeof(ps3_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -201,13 +201,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS4: - // 1. PS4-specific overrides + // PS4-specific overrides result = searchOverrides(ps4_overrides, sizeof(ps4_overrides) / sizeof(ps4_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -215,13 +215,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS5: - // 1. PS5-specific overrides + // PS5-specific overrides result = searchOverrides(ps5_overrides, sizeof(ps5_overrides) / sizeof(ps5_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -229,10 +229,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_NINTENDO_SWITCH: - // 1. Nintendo Switch specific overrides + // Nintendo Switch specific overrides result = searchOverrides(switch_specific, sizeof(switch_specific) / sizeof(switch_specific[0]), buttonIndex); if (result) return result; - // 2. Glyph standard (will fallback to generic prompts going forward) + // Glyph standard (will fallback to generic prompts going forward) break; case CONTROLLER_ICON_GENERIC: diff --git a/port/src/input.c b/port/src/input.c index 7e441c1096..d7f4847235 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1329,7 +1329,7 @@ void inputSetMouseLockMode(s32 lockmode) s32 inputGetButtonPromptOverride(s32 cidx) { if (cidx < 0 || cidx >= INPUT_MAX_CONTROLLERS) { - return 0; // Default to GLYPH_AUTO + return 0; } return padsCfg[cidx].buttonPromptOverride; } @@ -1374,70 +1374,73 @@ const char *inputGetKeyName(s32 vk) const char *inputGetButtonDisplayName(s32 vk) { - if (vk < 0 || vk >= VK_TOTAL_COUNT) { + if (vk < VK_JOY_BEGIN || vk >= VK_TOTAL_COUNT) { return inputGetKeyName(vk); } - if (vk >= VK_JOY_BEGIN && vk < VK_TOTAL_COUNT) { - const u32 cidx = (vk - VK_JOY_BEGIN) / INPUT_MAX_CONTROLLER_BUTTONS; - const u32 jbtn = (vk - VK_JOY_BEGIN) % INPUT_MAX_CONTROLLER_BUTTONS; - - if (jbtn < INPUT_MAX_CONTROLLER_BUTTONS) { - const s32 override = (cidx < INPUT_MAX_CONTROLLERS) ? padsCfg[cidx].buttonPromptOverride : GLYPH_AUTO; - - if (override == GLYPH_AUTO) { - if (cidx < INPUT_MAX_CONTROLLERS && pads[cidx]) { - const SDL_GameControllerType type = SDL_GameControllerGetType(pads[cidx]); - - switch (type) { - case SDL_CONTROLLER_TYPE_XBOX360: - return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); - case SDL_CONTROLLER_TYPE_XBOXONE: - return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); - case SDL_CONTROLLER_TYPE_PS3: - return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); - case SDL_CONTROLLER_TYPE_PS4: - return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + const u32 cidx = (vk - VK_JOY_BEGIN) / INPUT_MAX_CONTROLLER_BUTTONS; + const u32 jbtn = (vk - VK_JOY_BEGIN) % INPUT_MAX_CONTROLLER_BUTTONS; + + if (jbtn >= INPUT_MAX_CONTROLLER_BUTTONS) { + return inputGetKeyName(vk); + } + + const s32 override = (cidx < INPUT_MAX_CONTROLLERS) ? padsCfg[cidx].buttonPromptOverride : GLYPH_AUTO; + + // Internal glyphs (optional) + if (override == GLYPH_INTERNAL) { + if (jbtn < sizeof(vkJoyNames) / sizeof(vkJoyNames[0])) { + static char playerButtonName[64]; + const char *baseName = vkJoyNames[jbtn]; + snprintf(playerButtonName, sizeof(playerButtonName), "JOY%d_%s", + (int)(cidx + 1), baseName + 5); + return playerButtonName; + } + return inputGetKeyName(vk); + } + + // Glyph override + if (override != GLYPH_AUTO) { + const ControllerIconType iconType = (ControllerIconType)(override - 1); + return glyphGetButtonName(iconType, jbtn); + } + + // Auto-detect glyphs based on controller type + if (cidx < INPUT_MAX_CONTROLLERS && pads[cidx]) { + const SDL_GameControllerType type = SDL_GameControllerGetType(pads[cidx]); + switch (type) { + case SDL_CONTROLLER_TYPE_XBOX360: + return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + case SDL_CONTROLLER_TYPE_XBOXONE: + return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + case SDL_CONTROLLER_TYPE_PS3: + return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + case SDL_CONTROLLER_TYPE_PS4: + return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); #if SDL_VERSION_ATLEAST(2, 0, 14) - case SDL_CONTROLLER_TYPE_PS5: - return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + case SDL_CONTROLLER_TYPE_PS5: + return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); #endif - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: #if SDL_VERSION_ATLEAST(2, 24, 0) #if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: #endif #if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: #endif #if defined(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR) - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: #endif #endif - return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); - case SDL_CONTROLLER_TYPE_UNKNOWN: - default: - return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); - } - } + return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + default: return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); - } else if (override == GLYPH_INTERNAL) { - if (jbtn < sizeof(vkJoyNames) / sizeof(vkJoyNames[0])) { - static char playerButtonName[64]; - const char *baseName = vkJoyNames[jbtn]; - snprintf(playerButtonName, sizeof(playerButtonName), "JOY%d_%s", - (int)(cidx + 1), baseName + 5); - return playerButtonName; - } - return inputGetKeyName(vk); - } else { - const ControllerIconType iconType = (ControllerIconType)(override - 1); - return glyphGetButtonName(iconType, jbtn); - } } } - return inputGetKeyName(vk); + // Fallback to generic controller + return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); } s32 inputGetKeyByName(const char *name) diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 185655b3be..bc65fde906 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -622,7 +622,7 @@ static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, stru static const struct { const char *name; s32 value; - } promptOptions[] = { + } promptoptions [] = { { "Auto", GLYPH_AUTO }, { "Generic", GLYPH_GENERIC }, { "Internal", GLYPH_INTERNAL }, @@ -636,20 +636,18 @@ static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, stru switch (operation) { case MENUOP_GETOPTIONCOUNT: - data->dropdown.value = ARRAYCOUNT(promptOptions); + data->dropdown.value = ARRAYCOUNT(promptoptions); break; case MENUOP_GETOPTIONTEXT: - return (intptr_t)promptOptions[data->dropdown.value].name; + return (intptr_t)promptoptions[data->dropdown.value].name; case MENUOP_SET: - if (data->dropdown.value >= 0 && data->dropdown.value < ARRAYCOUNT(promptOptions)) { - inputSetButtonPromptOverride(g_ExtMenuPlayer, promptOptions[data->dropdown.value].value); - } + inputSetButtonPromptOverride(g_ExtMenuPlayer, promptoptions[data->dropdown.value].value); break; case MENUOP_GETSELECTEDINDEX: { s32 currentValue = inputGetButtonPromptOverride(g_ExtMenuPlayer); - for (s32 i = 0; i < ARRAYCOUNT(promptOptions); i++) { - if (promptOptions[i].value == currentValue) { + for (s32 i = 0; i < ARRAYCOUNT(promptoptions); i++) { + if (promptoptions[i].value == currentValue) { data->dropdown.value = i; return 0; } From e5d642a985c7f934de736fae573c105c90481e12 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 29 Jul 2025 20:01:52 -0400 Subject: [PATCH 09/33] remove duplicated Switch-specific prompts to use `glyph standard` --- port/src/glyph.c | 49 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index a7df407735..f5943a11d8 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -126,10 +126,6 @@ static const struct button_override ps5_overrides[] = { // Nintendo Switch-specific overrides static const struct button_override switch_specific[] = { - { 0, "B_BTN" }, // Nintendo bottom button → "B" equivalent - { 1, "A_BTN" }, // Nintendo right button → "A" equivalent - { 2, "Y_BTN" }, // Nintendo left button → "Y" equivalent - { 3, "X_BTN" }, // Nintendo top button → "X" equivalent { 4, "MINUS_BTN" }, { 5, "HOME_BTN" }, { 6, "PLUS_BTN" }, @@ -142,7 +138,7 @@ static const struct button_override switch_specific[] = { { 31, "ZR_TRIG" }, }; -// Helper function to search an override a specific button index +// Helper function to search an override array static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { for (int i = 0; i < count; i++) { if (overrides[i].button_index == buttonIndex) { @@ -162,10 +158,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // Xbox 360-specific overrides result = searchOverrides(xbox360_overrides, sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]), buttonIndex); if (result) return result; - // Xbox overrides + // 2. Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (Face Button only) + // 3. Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -173,13 +169,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_XBOXONE: - // Xbox One/Series X|S-specific overrides + // 1. Xbox One/Series X|S-specific overrides result = searchOverrides(xboxone_overrides, sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]), buttonIndex); if (result) return result; - // Xbox overrides + // 2. Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (Face Button only) + // 3. Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -190,10 +186,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // PS3-specific overrides result = searchOverrides(ps3_overrides, sizeof(ps3_overrides) / sizeof(ps3_overrides[0]), buttonIndex); if (result) return result; - // PlayStation overrides + // 2. PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (Face, Shoulders, Triggers only) + // 3. Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -201,13 +197,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS4: - // PS4-specific overrides + // 1. PS4-specific overrides result = searchOverrides(ps4_overrides, sizeof(ps4_overrides) / sizeof(ps4_overrides[0]), buttonIndex); if (result) return result; - // PlayStation overrides + // 2. PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (Face, Shoulders, Triggers only) + // 3. Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -215,13 +211,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS5: - // PS5-specific overrides + // 1. PS5-specific overrides result = searchOverrides(ps5_overrides, sizeof(ps5_overrides) / sizeof(ps5_overrides[0]), buttonIndex); if (result) return result; - // PlayStation overrides + // 2. PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (Face, Shoulders, Triggers only) + // 3. Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -229,10 +225,21 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_NINTENDO_SWITCH: - // Nintendo Switch specific overrides + // 1. Nintendo Switch specific overrides result = searchOverrides(switch_specific, sizeof(switch_specific) / sizeof(switch_specific[0]), buttonIndex); if (result) return result; - // Glyph standard (will fallback to generic prompts going forward) + // 2. Glyph standard (swapped Face Buttons positions) + if (buttonIndex >= 0 && buttonIndex <= 3) { + int mappedIndex = buttonIndex; + switch (buttonIndex) { + case 0: mappedIndex = 1; break; + case 1: mappedIndex = 0; break; + case 2: mappedIndex = 3; break; + case 3: mappedIndex = 2; break; + } + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), mappedIndex); + if (result) return result; + } break; case CONTROLLER_ICON_GENERIC: @@ -246,4 +253,4 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) } return "UNKNOWN BUTTON"; -} +} \ No newline at end of file From 4c800233b9ab08c6b79486bbb4990c76d25b5dd8 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 29 Jul 2025 20:20:31 -0400 Subject: [PATCH 10/33] restored original naming layout during the backporting process, the older names were brought over, but his has been fixed --- port/src/glyph.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index f5943a11d8..6701ed0ee4 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -138,7 +138,7 @@ static const struct button_override switch_specific[] = { { 31, "ZR_TRIG" }, }; -// Helper function to search an override array +// Function to search an override for a specific button index static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { for (int i = 0; i < count; i++) { if (overrides[i].button_index == buttonIndex) { @@ -158,10 +158,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // Xbox 360-specific overrides result = searchOverrides(xbox360_overrides, sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]), buttonIndex); if (result) return result; - // 2. Xbox overrides + // Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face Button only) + // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -169,13 +169,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_XBOXONE: - // 1. Xbox One/Series X|S-specific overrides + // Xbox One/Series X|S-specific overrides result = searchOverrides(xboxone_overrides, sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]), buttonIndex); if (result) return result; - // 2. Xbox overrides + // Xbox overrides result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face Button only) + // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -186,10 +186,10 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) // PS3-specific overrides result = searchOverrides(ps3_overrides, sizeof(ps3_overrides) / sizeof(ps3_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -197,13 +197,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS4: - // 1. PS4-specific overrides + // PS4-specific overrides result = searchOverrides(ps4_overrides, sizeof(ps4_overrides) / sizeof(ps4_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -211,13 +211,13 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_PS5: - // 1. PS5-specific overrides + // PS5-specific overrides result = searchOverrides(ps5_overrides, sizeof(ps5_overrides) / sizeof(ps5_overrides[0]), buttonIndex); if (result) return result; - // 2. PlayStation overrides + // PlayStation overrides result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); if (result) return result; - // 3. Glyph standard (Face, Shoulders, Triggers only) + // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); if (result) return result; @@ -225,17 +225,17 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) break; case CONTROLLER_ICON_NINTENDO_SWITCH: - // 1. Nintendo Switch specific overrides + // Nintendo Switch specific overrides result = searchOverrides(switch_specific, sizeof(switch_specific) / sizeof(switch_specific[0]), buttonIndex); if (result) return result; - // 2. Glyph standard (swapped Face Buttons positions) + // Glyph standard (swapped Face Buttons positions) if (buttonIndex >= 0 && buttonIndex <= 3) { int mappedIndex = buttonIndex; switch (buttonIndex) { - case 0: mappedIndex = 1; break; - case 1: mappedIndex = 0; break; - case 2: mappedIndex = 3; break; - case 3: mappedIndex = 2; break; + case 0: mappedIndex = 1; break; // B (Bottom face button) + case 1: mappedIndex = 0; break; // A (Right face button) + case 2: mappedIndex = 3; break; // Y (Left face button) + case 3: mappedIndex = 2; break; // X (Top face button) } result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), mappedIndex); if (result) return result; @@ -246,8 +246,8 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) default: break; } - - // Final fallback to generic names + + // Fallback to Generic type if (buttonIndex >= 0 && buttonIndex < 32) { return vkJoyDisplayNames[buttonIndex]; } From 075618e92ea2d5b918837e3f61cb30976f966051 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 29 Jul 2025 20:22:41 -0400 Subject: [PATCH 11/33] change notes one last time --- port/src/glyph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 6701ed0ee4..28476849b6 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -148,7 +148,7 @@ static const char* searchOverrides(const struct button_override* overrides, int return NULL; } -// Function to get controller-specific button name with fallback to generic +// Function to get controller-specific button names const char *glyphGetButtonName(int controllerType, int buttonIndex) { const char *result = NULL; From 49cc29f9ce263969bb6d5922aadf2a4526e3aebd Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Wed, 30 Jul 2025 22:51:46 -0400 Subject: [PATCH 12/33] added Steam Controller/Deck prompts, slightly corrected Paddle placement added support for Steam hardware prompts, while attempting to fix the button icon layout ordering to be a bit more consistent with SDL2 GameController Button mappings. --- port/include/glyph.h | 2 ++ port/include/input.h | 4 ++- port/src/glyph.c | 58 ++++++++++++++++++++++++++++++++++++------ port/src/input.c | 50 +++++++++++++++++++++++++++++------- port/src/optionsmenu.c | 4 ++- 5 files changed, 99 insertions(+), 19 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index a7abca75b5..40ba10aaaf 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -10,6 +10,8 @@ typedef enum { CONTROLLER_ICON_PS4, CONTROLLER_ICON_PS5, CONTROLLER_ICON_NINTENDO_SWITCH, + CONTROLLER_ICON_STEAM_CONTROLLER, + CONTROLLER_ICON_STEAM_DECK, } ControllerIconType; // Generic display names for controller buttons diff --git a/port/include/input.h b/port/include/input.h index f58eed783a..fb06965ae8 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -130,7 +130,9 @@ enum buttonpromptmode { GLYPH_PS3 = 4, GLYPH_PS4 = 5, GLYPH_PS5 = 6, - GLYPH_NINTENDO_SWITCH = 7 + GLYPH_NINTENDO_SWITCH = 7, + GLYPH_STEAM_CONTROLLER = 8, + GLYPH_STEAM_DECK = 9, }; // returns bitmask of connected controllers or -1 if failed diff --git a/port/src/glyph.c b/port/src/glyph.c index 28476849b6..475951403b 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -117,11 +117,13 @@ static const struct button_override ps4_overrides[] = { // PS5-specific button overrides static const struct button_override ps5_overrides[] = { - { 4, "CREATE_BTN" }, - { 6, "OPTIONS_BTN" }, - { 15, "MIC_BTN" }, // PS5 microphone mute button - { 18, "LB_PADDLE" }, // DualSense Edge left back button - { 19, "RB_PADDLE" }, // DualSense Edge right back button + { 4, "CREATE_BTN" }, + { 6, "OPTIONS_BTN" }, + { 15, "MIC_BTN" }, + { 16, "RB_PADDLE" }, // DualSense Edge RB Button + { 17, "LB_PADDLE" }, // DualSense Edge LB Button + { 18, "FN_RIGHT_BTN" }, // DualSense Edge right function button + { 19, "FN_LEFT_BTN" }, // DualSense Edge left function button }; // Nintendo Switch-specific overrides @@ -131,13 +133,28 @@ static const struct button_override switch_specific[] = { { 6, "PLUS_BTN" }, { 9, "L_SHOULDER" }, { 10, "R_SHOULDER" }, - { 15, "CAPTURE_BTN" }, - { 16, "SL_BTN" }, - { 17, "SR_BTN" }, + { 15, "CAPTURE_BTN" }, + { 16, "SL_BTN" }, // Left Joy-Con SL + { 17, "SR_BTN" }, // Left Joy-Con SR + { 18, "SL_BTN" }, // Right Joy-Con SL + { 19, "SR_BTN" }, // Right Joy-Con SR { 30, "ZL_TRIG" }, { 31, "ZR_TRIG" }, }; +// Steam Deck-specific overrides +static const struct button_override steamdeck_overrides[] = { + { 4, "VIEW_BTN" }, + { 6, "MENU_BTN" }, +}; + +// Steam Controller-specific overrides +static const struct button_override steamcontroller_overrides[] = { + { 16, "RG_BTN" }, // Steam Controller left grip + { 17, "LG_BTN" }, // Steam Controller right grip +}; + + // Function to search an override for a specific button index static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { for (int i = 0; i < count; i++) { @@ -167,6 +184,20 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) if (result) return result; } break; + + case CONTROLLER_ICON_STEAM_CONTROLLER: + // Steam Controller-specific overrides + result = searchOverrides(steamcontroller_overrides, sizeof(steamcontroller_overrides) / sizeof(steamcontroller_overrides[0]), buttonIndex); + if (result) return result; + // Xbox overrides (Shoulders and triggers) + result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + if (result) return result; + // Glyph standard (Face buttons) + if (buttonIndex >= 0 && buttonIndex <= 3) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; + } + break; case CONTROLLER_ICON_XBOXONE: // Xbox One/Series X|S-specific overrides @@ -241,6 +272,17 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) if (result) return result; } break; + + case CONTROLLER_ICON_STEAM_DECK: + // Steam Deck-specific overrides + result = searchOverrides(steamdeck_overrides, sizeof(steamdeck_overrides) / sizeof(steamdeck_overrides[0]), buttonIndex); + if (result) return result; + // Glyph standard + if ((buttonIndex >= 0 && buttonIndex <= 19) || (buttonIndex >= 30 && buttonIndex <= 31)) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; + } + break; case CONTROLLER_ICON_GENERIC: default: diff --git a/port/src/input.c b/port/src/input.c index d7f4847235..c6232d761e 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1377,28 +1377,37 @@ const char *inputGetButtonDisplayName(s32 vk) if (vk < VK_JOY_BEGIN || vk >= VK_TOTAL_COUNT) { return inputGetKeyName(vk); } - + const u32 cidx = (vk - VK_JOY_BEGIN) / INPUT_MAX_CONTROLLER_BUTTONS; - const u32 jbtn = (vk - VK_JOY_BEGIN) % INPUT_MAX_CONTROLLER_BUTTONS; - + u32 jbtn = (vk - VK_JOY_BEGIN) % INPUT_MAX_CONTROLLER_BUTTONS; + if (jbtn >= INPUT_MAX_CONTROLLER_BUTTONS) { return inputGetKeyName(vk); } - + const s32 override = (cidx < INPUT_MAX_CONTROLLERS) ? padsCfg[cidx].buttonPromptOverride : GLYPH_AUTO; - + // Internal glyphs (optional) if (override == GLYPH_INTERNAL) { if (jbtn < sizeof(vkJoyNames) / sizeof(vkJoyNames[0])) { static char playerButtonName[64]; const char *baseName = vkJoyNames[jbtn]; - snprintf(playerButtonName, sizeof(playerButtonName), "JOY%d_%s", + snprintf(playerButtonName, sizeof(playerButtonName), "JOY%d_%s", (int)(cidx + 1), baseName + 5); return playerButtonName; } return inputGetKeyName(vk); } - + + // Use glyphs based on controller type + SDL_GameController *ctrl = (cidx < INPUT_MAX_CONTROLLERS) ? pads[cidx] : NULL; + SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; +#if SDL_VERSION_ATLEAST(2, 0, 12) + if (ctrl) { + type = SDL_GameControllerGetType(ctrl); + } +#endif + // Glyph override if (override != GLYPH_AUTO) { const ControllerIconType iconType = (ControllerIconType)(override - 1); @@ -1434,12 +1443,35 @@ const char *inputGetButtonDisplayName(s32 vk) #endif #endif return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + case SDL_CONTROLLER_TYPE_VIRTUAL: + // Check for Steam Controllers by VID/PID + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + Uint16 product = SDL_JoystickGetProduct(joystick); + + if (vendor == 0x28de) { // Valve Corporation + // Steam Controllers + if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + product == 0x1106 || product == 0x1142 || product == 0x1201 || + product == 0x1202) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); + } + // Steam Deck + else if (product == 0x1205) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + } + } + } + case SDL_CONTROLLER_TYPE_UNKNOWN: default: return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); } } - // Fallback to generic controller + // fallback to generic type if no controller is connected or recognized return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); } @@ -1626,7 +1658,7 @@ PD_CONSTRUCTOR static void inputConfigInit(void) configRegisterInt(strFmt("%s.CancelCButtons", secname), &padsCfg[c].cancelCButtons, 0, 1); configRegisterInt(strFmt("%s.SwapSticks", secname), &padsCfg[c].swapSticks, 0, 1); configRegisterInt(strFmt("%s.ControllerIndex", secname), &padsCfg[c].deviceIndex, -1, 0x7FFFFFFF); - configRegisterInt(strFmt("%s.ButtonPromptOverride", secname), &padsCfg[c].buttonPromptOverride, GLYPH_AUTO, GLYPH_NINTENDO_SWITCH); + configRegisterInt(strFmt("%s.ButtonPromptOverride", secname), &padsCfg[c].buttonPromptOverride, GLYPH_AUTO, GLYPH_STEAM_DECK); secname[13] = '.'; for (u32 ck = 0; ck < CK_TOTAL_COUNT; ++ck) { snprintf(keyname, sizeof(keyname), "%s.%s", secname, inputGetContKeyName(ck)); diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index bc65fde906..e83075e2b3 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -631,7 +631,9 @@ static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, stru { "DualShock 3", GLYPH_PS3 }, { "DualShock 4", GLYPH_PS4 }, { "DualSense", GLYPH_PS5 }, - { "Nintendo Switch Controller", GLYPH_NINTENDO_SWITCH } + { "Nintendo Switch Controller", GLYPH_NINTENDO_SWITCH }, + { "Steam Controller", GLYPH_STEAM_CONTROLLER }, + { "Steam Deck", GLYPH_STEAM_DECK } }; switch (operation) { From 1b787e448a425dc49ab5f3ba67bf998cbcb47d02 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Wed, 30 Jul 2025 23:30:04 -0400 Subject: [PATCH 13/33] fixed Steam Virtual Gamepad detection it should now detect Steam Deck prompts via Steam Virtual Gamepad...i hope? --- port/src/input.c | 52 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index c6232d761e..7e76c857f3 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1399,7 +1399,6 @@ const char *inputGetButtonDisplayName(s32 vk) return inputGetKeyName(vk); } - // Use glyphs based on controller type SDL_GameController *ctrl = (cidx < INPUT_MAX_CONTROLLERS) ? pads[cidx] : NULL; SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; #if SDL_VERSION_ATLEAST(2, 0, 12) @@ -1417,6 +1416,8 @@ const char *inputGetButtonDisplayName(s32 vk) // Auto-detect glyphs based on controller type if (cidx < INPUT_MAX_CONTROLLERS && pads[cidx]) { const SDL_GameControllerType type = SDL_GameControllerGetType(pads[cidx]); + + // First check SDL controller type detection switch (type) { case SDL_CONTROLLER_TYPE_XBOX360: return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); @@ -1444,30 +1445,35 @@ const char *inputGetButtonDisplayName(s32 vk) #endif return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: - // Check for Steam Controllers by VID/PID - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - Uint16 product = SDL_JoystickGetProduct(joystick); - - if (vendor == 0x28de) { // Valve Corporation - // Steam Controllers - if (product == 0x1101 || product == 0x1102 || product == 0x1105 || - product == 0x1106 || product == 0x1142 || product == 0x1201 || - product == 0x1202) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); - } - // Steam Deck - else if (product == 0x1205) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - } - } - } case SDL_CONTROLLER_TYPE_UNKNOWN: default: - return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + break; + } + + // If SDL controller type detection didn't match, try VID/PID detection + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + if (vendor == 0x28de) { // Valve Corporation + Uint16 product = SDL_JoystickGetProduct(joystick); + + // Steam Controllers (all variants) + if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + product == 0x1106 || product == 0x1142 || product == 0x1201 || + product == 0x1202) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); + } + // Steam Deck + else if (product == 0x1205) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + else { + // Default to generic for other Valve-related devices (including virtual gamepad) + return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + } + } + } } } From d88b4e01eeb9c0ab0a3f95c5769229262f877e2c Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Wed, 30 Jul 2025 23:34:22 -0400 Subject: [PATCH 14/33] removed some leftover notes during testing Steam Virtual Gamepad --- port/src/input.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 7e76c857f3..1e101fb2a6 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1387,7 +1387,7 @@ const char *inputGetButtonDisplayName(s32 vk) const s32 override = (cidx < INPUT_MAX_CONTROLLERS) ? padsCfg[cidx].buttonPromptOverride : GLYPH_AUTO; - // Internal glyphs (optional) + // Internal glyphs (legacy) if (override == GLYPH_INTERNAL) { if (jbtn < sizeof(vkJoyNames) / sizeof(vkJoyNames[0])) { static char playerButtonName[64]; @@ -1407,7 +1407,7 @@ const char *inputGetButtonDisplayName(s32 vk) } #endif - // Glyph override + // Glyph override function if (override != GLYPH_AUTO) { const ControllerIconType iconType = (ControllerIconType)(override - 1); return glyphGetButtonName(iconType, jbtn); @@ -1417,7 +1417,6 @@ const char *inputGetButtonDisplayName(s32 vk) if (cidx < INPUT_MAX_CONTROLLERS && pads[cidx]) { const SDL_GameControllerType type = SDL_GameControllerGetType(pads[cidx]); - // First check SDL controller type detection switch (type) { case SDL_CONTROLLER_TYPE_XBOX360: return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); @@ -1450,7 +1449,6 @@ const char *inputGetButtonDisplayName(s32 vk) break; } - // If SDL controller type detection didn't match, try VID/PID detection if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick) { From 92304bf44914a81284b6716266e912260143c07e Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Wed, 30 Jul 2025 23:46:12 -0400 Subject: [PATCH 15/33] added VID/PID to Steam Virtual Gamepad for some reason: it's it own thing, we'll do one last ditch effort on fixing the detection issue once and for all. --- port/src/input.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 1e101fb2a6..9509e57420 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1466,9 +1466,13 @@ const char *inputGetButtonDisplayName(s32 vk) else if (product == 0x1205) { return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } + // Steam Virtual Gamepad + else if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } else { - // Default to generic for other Valve-related devices (including virtual gamepad) - return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + // Default to Steam Deck for other Valve-related devices + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } } } From 3191b29d36cf01235922cb0b553e6d19f3b5cf98 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 31 Jul 2025 06:58:46 -0400 Subject: [PATCH 16/33] revised Steam Virtual Gamepad detection --- port/src/input.c | 94 ++++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 34 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 9509e57420..eb708e0380 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1372,6 +1372,7 @@ const char *inputGetKeyName(s32 vk) return vkNames[vk]; } + const char *inputGetButtonDisplayName(s32 vk) { if (vk < VK_JOY_BEGIN || vk >= VK_TOTAL_COUNT) { @@ -1400,12 +1401,6 @@ const char *inputGetButtonDisplayName(s32 vk) } SDL_GameController *ctrl = (cidx < INPUT_MAX_CONTROLLERS) ? pads[cidx] : NULL; - SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; -#if SDL_VERSION_ATLEAST(2, 0, 12) - if (ctrl) { - type = SDL_GameControllerGetType(ctrl); - } -#endif // Glyph override function if (override != GLYPH_AUTO) { @@ -1419,15 +1414,45 @@ const char *inputGetButtonDisplayName(s32 vk) switch (type) { case SDL_CONTROLLER_TYPE_XBOX360: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); case SDL_CONTROLLER_TYPE_XBOXONE: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); case SDL_CONTROLLER_TYPE_PS3: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); case SDL_CONTROLLER_TYPE_PS4: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLER_TYPE_PS5: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); #endif case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: @@ -1442,40 +1467,41 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: #endif #endif + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + } + } return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: case SDL_CONTROLLER_TYPE_UNKNOWN: default: - break; - } - - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == 0x28de) { // Valve Corporation - Uint16 product = SDL_JoystickGetProduct(joystick); - - // Steam Controllers (all variants) - if (product == 0x1101 || product == 0x1102 || product == 0x1105 || - product == 0x1106 || product == 0x1142 || product == 0x1201 || - product == 0x1202) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); - } - // Steam Deck - else if (product == 0x1205) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - // Steam Virtual Gamepad - else if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - else { - // Default to Steam Deck for other Valve-related devices - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + if (vendor == 0x28de) { // Valve Corporation + Uint16 product = SDL_JoystickGetProduct(joystick); + + // Physical Steam Controllers + if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + product == 0x1106 || product == 0x1142 || product == 0x1201 || + product == 0x1202) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); + } + // Steam Deck + else if (product == 0x1205) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + // Steam Virtual Gamepad or other Valve devices + else { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + } } } - } + break; } } From e83c9eb1595ca9aa56cefbab37bc635464fdbbc4 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:01:49 -0400 Subject: [PATCH 17/33] second attempt on improving Steam Virtual Gamepad detection --- port/src/input.c | 81 +++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index eb708e0380..930b7ea45f 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1372,7 +1372,6 @@ const char *inputGetKeyName(s32 vk) return vkNames[vk]; } - const char *inputGetButtonDisplayName(s32 vk) { if (vk < VK_JOY_BEGIN || vk >= VK_TOTAL_COUNT) { @@ -1417,7 +1416,10 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); @@ -1425,7 +1427,10 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); @@ -1433,7 +1438,10 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); @@ -1441,7 +1449,10 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); @@ -1450,7 +1461,10 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); @@ -1470,38 +1484,41 @@ const char *inputGetButtonDisplayName(s32 vk) if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { - return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + Uint16 product = SDL_JoystickGetProduct(joystick); + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + } } } return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: case SDL_CONTROLLER_TYPE_UNKNOWN: default: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == 0x28de) { // Valve Corporation - Uint16 product = SDL_JoystickGetProduct(joystick); - - // Physical Steam Controllers - if (product == 0x1101 || product == 0x1102 || product == 0x1105 || - product == 0x1106 || product == 0x1142 || product == 0x1201 || - product == 0x1202) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); - } - // Steam Deck - else if (product == 0x1205) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - // Steam Virtual Gamepad or other Valve devices - else { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - } - } - } - break; + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + if (vendor == 0x28de) { // Valve Corporation + Uint16 product = SDL_JoystickGetProduct(joystick); + + // Steam Virtual Gamepad + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + // Steam Controllers + else if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + product == 0x1106 || product == 0x1142 || product == 0x1201 || + product == 0x1202) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); + } + // Steam Deck + else if (product == 0x1205) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + } + } + } + break; } } From 866480e94983eda630b34f52e6a8540b513a5f68 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:07:43 -0400 Subject: [PATCH 18/33] moved Steam Virtual Gamepad onto `SDL_CONTROLLER_TYPE_VIRTUAL` --- port/src/input.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 930b7ea45f..9bda03394f 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1492,6 +1492,21 @@ const char *inputGetButtonDisplayName(s32 vk) } return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + if (vendor == 0x28de) { // Valve Corporation + Uint16 product = SDL_JoystickGetProduct(joystick); + + // Steam Virtual Gamepad + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } + } + } + } + break; case SDL_CONTROLLER_TYPE_UNKNOWN: default: if (ctrl) { @@ -1501,12 +1516,8 @@ const char *inputGetButtonDisplayName(s32 vk) if (vendor == 0x28de) { // Valve Corporation Uint16 product = SDL_JoystickGetProduct(joystick); - // Steam Virtual Gamepad - if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } // Steam Controllers - else if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + if (product == 0x1101 || product == 0x1102 || product == 0x1105 || product == 0x1106 || product == 0x1142 || product == 0x1201 || product == 0x1202) { return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); From ed23dcdd8f5e946befdd5264f2700270522ba1d2 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:20:52 -0400 Subject: [PATCH 19/33] Revert "moved Steam Virtual Gamepad onto `SDL_CONTROLLER_TYPE_VIRTUAL`" This reverts commit 866480e94983eda630b34f52e6a8540b513a5f68. --- port/src/input.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 9bda03394f..930b7ea45f 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1492,21 +1492,6 @@ const char *inputGetButtonDisplayName(s32 vk) } return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == 0x28de) { // Valve Corporation - Uint16 product = SDL_JoystickGetProduct(joystick); - - // Steam Virtual Gamepad - if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - } - } - } - break; case SDL_CONTROLLER_TYPE_UNKNOWN: default: if (ctrl) { @@ -1516,8 +1501,12 @@ const char *inputGetButtonDisplayName(s32 vk) if (vendor == 0x28de) { // Valve Corporation Uint16 product = SDL_JoystickGetProduct(joystick); + // Steam Virtual Gamepad + if (product == 0x11ff) { + return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + } // Steam Controllers - if (product == 0x1101 || product == 0x1102 || product == 0x1105 || + else if (product == 0x1101 || product == 0x1102 || product == 0x1105 || product == 0x1106 || product == 0x1142 || product == 0x1201 || product == 0x1202) { return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); From 64600001c87b0192fce1ed5a1e8e1eafe320070f Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Sun, 3 Aug 2025 17:59:02 -0400 Subject: [PATCH 20/33] added Nintendo 64 Controller glyphs added optional glyph support for N64 Controller, although: the mappings are based upon Nintendo Switch Online variant. due to that: actual mappings are using Nintendo Switch Pro Controller's protocol as a basis. --- port/include/glyph.h | 7 ++++++- port/include/input.h | 5 +++-- port/src/glyph.c | 39 ++++++++++++++++++++++++++++++++++----- port/src/input.c | 39 ++++++++++++++++++++++----------------- port/src/optionsmenu.c | 1 + 5 files changed, 66 insertions(+), 25 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index 40ba10aaaf..53feaf8a35 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -10,6 +10,7 @@ typedef enum { CONTROLLER_ICON_PS4, CONTROLLER_ICON_PS5, CONTROLLER_ICON_NINTENDO_SWITCH, + CONTROLLER_ICON_NINTENDO_64, CONTROLLER_ICON_STEAM_CONTROLLER, CONTROLLER_ICON_STEAM_DECK, } ControllerIconType; @@ -18,6 +19,10 @@ typedef enum { extern const char *vkJoyDisplayNames[]; // Function to get controller-specific button name with fallback to generic -const char *glyphGetButtonName(int controllerType, int buttonIndex); +const char *glyphGetControllerButtonName(int controllerType, int buttonIndex); + +// Function to replace baked-in button text with dynamic controller bindings +char* glyphInputBindingDetect(char* text, int textSize, const char* placeholder, + int controllerIndex, int controlKey, int forceController); #endif \ No newline at end of file diff --git a/port/include/input.h b/port/include/input.h index fb06965ae8..d8370240db 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -131,8 +131,9 @@ enum buttonpromptmode { GLYPH_PS4 = 5, GLYPH_PS5 = 6, GLYPH_NINTENDO_SWITCH = 7, - GLYPH_STEAM_CONTROLLER = 8, - GLYPH_STEAM_DECK = 9, + GLYPH_NINTENDO_64 = 8, + GLYPH_STEAM_CONTROLLER = 9, + GLYPH_STEAM_DECK = 10, }; // returns bitmask of connected controllers or -1 if failed diff --git a/port/src/glyph.c b/port/src/glyph.c index 475951403b..5f642c9955 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -127,7 +127,7 @@ static const struct button_override ps5_overrides[] = { }; // Nintendo Switch-specific overrides -static const struct button_override switch_specific[] = { +static const struct button_override nintendoswitch_override[] = { { 4, "MINUS_BTN" }, { 5, "HOME_BTN" }, { 6, "PLUS_BTN" }, @@ -145,15 +145,28 @@ static const struct button_override switch_specific[] = { // Steam Deck-specific overrides static const struct button_override steamdeck_overrides[] = { { 4, "VIEW_BTN" }, + { 5, "STEAM_BTN" }, { 6, "MENU_BTN" }, }; // Steam Controller-specific overrides static const struct button_override steamcontroller_overrides[] = { - { 16, "RG_BTN" }, // Steam Controller left grip - { 17, "LG_BTN" }, // Steam Controller right grip + { 5, "STEAM_BTN" }, + { 16, "RG_BTN" }, // Steam Controller left grip + { 17, "LG_BTN" }, // Steam Controller right grip }; +// Nintendo 64-specific overrides (based on NSO N64 controller's button layout) +static const struct button_override nintendo64_overrides[] = { + { 2, "C-LEFT_BTN" }, + { 3, "C-UP_BTN" }, + { 4, "C-RIGHT_BTN" }, + { 6, "START_BTN" }, + { 9, "L_BTN" }, + { 10, "R_BTN" }, + { 30, "C-DOWN_BTN" }, + { 31, "Z_BTN" }, +}; // Function to search an override for a specific button index static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { @@ -166,7 +179,7 @@ static const char* searchOverrides(const struct button_override* overrides, int } // Function to get controller-specific button names -const char *glyphGetButtonName(int controllerType, int buttonIndex) +const char *glyphGetControllerButtonName(int controllerType, int buttonIndex) { const char *result = NULL; @@ -257,7 +270,7 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) case CONTROLLER_ICON_NINTENDO_SWITCH: // Nintendo Switch specific overrides - result = searchOverrides(switch_specific, sizeof(switch_specific) / sizeof(switch_specific[0]), buttonIndex); + result = searchOverrides(nintendoswitch_override, sizeof(nintendoswitch_override) / sizeof(nintendoswitch_override[0]), buttonIndex); if (result) return result; // Glyph standard (swapped Face Buttons positions) if (buttonIndex >= 0 && buttonIndex <= 3) { @@ -273,6 +286,22 @@ const char *glyphGetButtonName(int controllerType, int buttonIndex) } break; + case CONTROLLER_ICON_NINTENDO_64: + // Nintendo 64-specific overrides + result = searchOverrides(nintendo64_overrides, sizeof(nintendo64_overrides) / sizeof(nintendo64_overrides[0]), buttonIndex); + if (result) return result; + // Nintendo Switch specific overrides (for NSO N64 controller's Home and Capture buttons) + if (buttonIndex == 5 || buttonIndex == 15) { + result = searchOverrides(nintendoswitch_override, sizeof(nintendoswitch_override) / sizeof(nintendoswitch_override[0]), buttonIndex); + if (result) return result; + } + // Glyph standard (N64 face buttons) + if (buttonIndex >= 0 && buttonIndex <= 1) { + result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + if (result) return result; + } + break; + case CONTROLLER_ICON_STEAM_DECK: // Steam Deck-specific overrides result = searchOverrides(steamdeck_overrides, sizeof(steamdeck_overrides) / sizeof(steamdeck_overrides[0]), buttonIndex); diff --git a/port/src/input.c b/port/src/input.c index 930b7ea45f..db96c7cd82 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1399,12 +1399,17 @@ const char *inputGetButtonDisplayName(s32 vk) return inputGetKeyName(vk); } + // Nintendo 64 controller prompts + if (override == GLYPH_NINTENDO_64) { + return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_64, jbtn); + } + SDL_GameController *ctrl = (cidx < INPUT_MAX_CONTROLLERS) ? pads[cidx] : NULL; // Glyph override function if (override != GLYPH_AUTO) { const ControllerIconType iconType = (ControllerIconType)(override - 1); - return glyphGetButtonName(iconType, jbtn); + return glyphGetControllerButtonName(iconType, jbtn); } // Auto-detect glyphs based on controller type @@ -1418,44 +1423,44 @@ const char *inputGetButtonDisplayName(s32 vk) if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_XBOX360, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_XBOX360, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_XBOX360, jbtn); case SDL_CONTROLLER_TYPE_XBOXONE: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_XBOXONE, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_XBOXONE, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_XBOXONE, jbtn); case SDL_CONTROLLER_TYPE_PS3: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS3, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_PS3, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS3, jbtn); case SDL_CONTROLLER_TYPE_PS4: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS4, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_PS4, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS4, jbtn); #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLER_TYPE_PS5: if (ctrl) { @@ -1463,11 +1468,11 @@ const char *inputGetButtonDisplayName(s32 vk) if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS5, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_PS5, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_PS5, jbtn); #endif case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: #if SDL_VERSION_ATLEAST(2, 24, 0) @@ -1486,11 +1491,11 @@ const char *inputGetButtonDisplayName(s32 vk) if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { Uint16 product = SDL_JoystickGetProduct(joystick); if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); } } } - return glyphGetButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); case SDL_CONTROLLER_TYPE_VIRTUAL: case SDL_CONTROLLER_TYPE_UNKNOWN: default: @@ -1503,17 +1508,17 @@ const char *inputGetButtonDisplayName(s32 vk) // Steam Virtual Gamepad if (product == 0x11ff) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } // Steam Controllers else if (product == 0x1101 || product == 0x1102 || product == 0x1105 || product == 0x1106 || product == 0x1142 || product == 0x1201 || product == 0x1202) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); } // Steam Deck else if (product == 0x1205) { - return glyphGetButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } } } @@ -1523,7 +1528,7 @@ const char *inputGetButtonDisplayName(s32 vk) } // fallback to generic type if no controller is connected or recognized - return glyphGetButtonName(CONTROLLER_ICON_GENERIC, jbtn); + return glyphGetControllerButtonName(CONTROLLER_ICON_GENERIC, jbtn); } s32 inputGetKeyByName(const char *name) diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index e83075e2b3..55375085a9 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -632,6 +632,7 @@ static MenuItemHandlerResult menuhandlerButtonPromptOverride(s32 operation, stru { "DualShock 4", GLYPH_PS4 }, { "DualSense", GLYPH_PS5 }, { "Nintendo Switch Controller", GLYPH_NINTENDO_SWITCH }, + { "Nintendo 64 Controller", GLYPH_NINTENDO_64 }, { "Steam Controller", GLYPH_STEAM_CONTROLLER }, { "Steam Deck", GLYPH_STEAM_DECK } }; From ab6d1328d2c7000b5d7cd8cb05ec0b35bbce034f Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 00:18:15 -0400 Subject: [PATCH 21/33] modularized Steam hardware vid/pid moved PID/VID over to glyph.h for easier organization --- port/include/glyph.h | 29 +++++++++++++++++++++++++++++ port/src/input.c | 34 ++++++++++++++++------------------ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index 53feaf8a35..092acbb098 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -1,6 +1,8 @@ #ifndef _IN_GLYPH_H #define _IN_GLYPH_H +#include + // Controller Icon enumeration for button icon detection typedef enum { CONTROLLER_ICON_GENERIC, @@ -15,6 +17,33 @@ typedef enum { CONTROLLER_ICON_STEAM_DECK, } ControllerIconType; +// Steam/Valve Corporation VID/PID definitions +#define VALVE_VENDOR_ID 0x28de + +// Steam Controller product IDs (all generations) +#define STEAM_CONTROLLER_LEGACY_PID 0x1101 // Valve Legacy Steam Controller (CHELL) +#define STEAM_CONTROLLER_WIRED_PID 0x1102 // Valve wired Steam Controller (D0G) +#define STEAM_CONTROLLER_BT_1_PID 0x1105 // Valve Bluetooth Steam Controller (D0G) +#define STEAM_CONTROLLER_BT_2_PID 0x1106 // Valve Bluetooth Steam Controller (D0G) +#define STEAM_CONTROLLER_WIRELESS_PID 0x1142 // Valve wireless Steam Controller +#define STEAM_CONTROLLER_V2_WIRED_PID 0x1201 // Valve wired Steam Controller (HEADCRAB) +#define STEAM_CONTROLLER_V2_BT_PID 0x1202 // Valve Bluetooth Steam Controller (HEADCRAB) + +// Other Steam/Valve product IDs +#define STEAM_VIRTUAL_GAMEPAD_PID 0x11ff // Steam Virtual Gamepad +#define STEAM_DECK_BUILTIN_PID 0x1205 // Valve Steam Deck Builtin + +// Helper function to check if a product ID is any Steam Controller variant +static inline int isSteamControllerPID(unsigned short productId) { + return (productId == STEAM_CONTROLLER_LEGACY_PID || + productId == STEAM_CONTROLLER_WIRED_PID || + productId == STEAM_CONTROLLER_BT_1_PID || + productId == STEAM_CONTROLLER_BT_2_PID || + productId == STEAM_CONTROLLER_WIRELESS_PID || + productId == STEAM_CONTROLLER_V2_WIRED_PID || + productId == STEAM_CONTROLLER_V2_BT_PID); +} + // Generic display names for controller buttons extern const char *vkJoyDisplayNames[]; diff --git a/port/src/input.c b/port/src/input.c index db96c7cd82..e7702ce1db 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1420,9 +1420,9 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_XBOX360: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_XBOX360, jbtn); } } @@ -1431,9 +1431,9 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_XBOXONE: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_XBOXONE, jbtn); } } @@ -1442,9 +1442,9 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_PS3: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_PS3, jbtn); } } @@ -1453,9 +1453,9 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_PS4: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_PS4, jbtn); } } @@ -1465,9 +1465,9 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_PS5: if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_PS5, jbtn); } } @@ -1488,9 +1488,9 @@ const char *inputGetButtonDisplayName(s32 vk) #endif if (ctrl) { SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == 0x28de) { + if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); } } @@ -1503,21 +1503,19 @@ const char *inputGetButtonDisplayName(s32 vk) SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (joystick) { Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == 0x28de) { // Valve Corporation + if (vendor == VALVE_VENDOR_ID) { // Valve Corporation Uint16 product = SDL_JoystickGetProduct(joystick); // Steam Virtual Gamepad - if (product == 0x11ff) { + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } // Steam Controllers - else if (product == 0x1101 || product == 0x1102 || product == 0x1105 || - product == 0x1106 || product == 0x1142 || product == 0x1201 || - product == 0x1202) { + else if (isSteamControllerPID(product)) { return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); } // Steam Deck - else if (product == 0x1205) { + else if (product == STEAM_DECK_BUILTIN_PID) { return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); } } From 9b4e7e3140afc67feb4d9891edb8bf1a5ba1e916 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 01:02:29 -0400 Subject: [PATCH 22/33] experimental simplified SteamVirtualGamepad function --- port/include/glyph.h | 21 ++++++++ port/src/input.c | 119 ++++++++++++++++--------------------------- 2 files changed, 64 insertions(+), 76 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index 092acbb098..dc2b1c9efe 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -44,6 +44,27 @@ static inline int isSteamControllerPID(unsigned short productId) { productId == STEAM_CONTROLLER_V2_BT_PID); } +// Helper function to handle Steam Virtual Gamepad hybrid approach +static inline int getSteamVirtualControllerDetection(SDL_GameController* ctrl, int fallbackControllerType) { + if (!ctrl) { + return fallbackControllerType; + } + + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (!joystick || SDL_JoystickGetVendor(joystick) != VALVE_VENDOR_ID) { + return fallbackControllerType; + } + + unsigned short product = SDL_JoystickGetProduct(joystick); + + // Steam Virtual Gamepad: Use the controller type's default glyphs (hybrid approach) + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { + return fallbackControllerType; + } + + return fallbackControllerType; +} + // Generic display names for controller buttons extern const char *vkJoyDisplayNames[]; diff --git a/port/src/input.c b/port/src/input.c index e7702ce1db..53be48ff0d 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1418,61 +1418,31 @@ const char *inputGetButtonDisplayName(s32 vk) switch (type) { case SDL_CONTROLLER_TYPE_XBOX360: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_XBOX360, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_XBOX360); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_XBOX360, jbtn); case SDL_CONTROLLER_TYPE_XBOXONE: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_XBOXONE, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_XBOXONE); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_XBOXONE, jbtn); case SDL_CONTROLLER_TYPE_PS3: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_PS3, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_PS3); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_PS3, jbtn); case SDL_CONTROLLER_TYPE_PS4: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_PS4, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_PS4); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_PS4, jbtn); #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLER_TYPE_PS5: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_PS5, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_PS5); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_PS5, jbtn); #endif case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: #if SDL_VERSION_ATLEAST(2, 24, 0) @@ -1486,42 +1456,39 @@ const char *inputGetButtonDisplayName(s32 vk) case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: #endif #endif - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick && SDL_JoystickGetVendor(joystick) == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); - } - } + { + int iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_NINTENDO_SWITCH); + return glyphGetControllerButtonName(iconType, jbtn); } - return glyphGetControllerButtonName(CONTROLLER_ICON_NINTENDO_SWITCH, jbtn); - case SDL_CONTROLLER_TYPE_VIRTUAL: - case SDL_CONTROLLER_TYPE_UNKNOWN: - default: - if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == VALVE_VENDOR_ID) { // Valve Corporation - Uint16 product = SDL_JoystickGetProduct(joystick); - - // Steam Virtual Gamepad - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); - } - // Steam Controllers - else if (isSteamControllerPID(product)) { - return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_CONTROLLER, jbtn); - } - // Steam Deck - else if (product == STEAM_DECK_BUILTIN_PID) { - return glyphGetControllerButtonName(CONTROLLER_ICON_STEAM_DECK, jbtn); + case SDL_CONTROLLER_TYPE_VIRTUAL: + case SDL_CONTROLLER_TYPE_UNKNOWN: + default: + { + int iconType = CONTROLLER_ICON_GENERIC; + if (ctrl) { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); + if (joystick) { + Uint16 vendor = SDL_JoystickGetVendor(joystick); + if (vendor == VALVE_VENDOR_ID) { + Uint16 product = SDL_JoystickGetProduct(joystick); + + // Steam Virtual Gamepad + if (product == STEAM_VIRTUAL_GAMEPAD_PID) { + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); + } + // Steam Controller + else if (isSteamControllerPID(product)) { + iconType = CONTROLLER_ICON_STEAM_CONTROLLER; + } + // Steam Deck + else if (product == STEAM_DECK_BUILTIN_PID) { + iconType = CONTROLLER_ICON_STEAM_DECK; + } } } } + return glyphGetControllerButtonName(iconType, jbtn); } - break; } } From 9381c419586e04fbe61e5f669349693d40078836 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 01:07:04 -0400 Subject: [PATCH 23/33] changed some of the notes and name fuction --- port/include/glyph.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index dc2b1c9efe..985b00b500 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -17,10 +17,10 @@ typedef enum { CONTROLLER_ICON_STEAM_DECK, } ControllerIconType; -// Steam/Valve Corporation VID/PID definitions +// Valve Corporation VID/PID definitions #define VALVE_VENDOR_ID 0x28de -// Steam Controller product IDs (all generations) +// Steam Controller product IDs #define STEAM_CONTROLLER_LEGACY_PID 0x1101 // Valve Legacy Steam Controller (CHELL) #define STEAM_CONTROLLER_WIRED_PID 0x1102 // Valve wired Steam Controller (D0G) #define STEAM_CONTROLLER_BT_1_PID 0x1105 // Valve Bluetooth Steam Controller (D0G) @@ -29,11 +29,11 @@ typedef enum { #define STEAM_CONTROLLER_V2_WIRED_PID 0x1201 // Valve wired Steam Controller (HEADCRAB) #define STEAM_CONTROLLER_V2_BT_PID 0x1202 // Valve Bluetooth Steam Controller (HEADCRAB) -// Other Steam/Valve product IDs +// Other Valve product IDs #define STEAM_VIRTUAL_GAMEPAD_PID 0x11ff // Steam Virtual Gamepad #define STEAM_DECK_BUILTIN_PID 0x1205 // Valve Steam Deck Builtin -// Helper function to check if a product ID is any Steam Controller variant +// Check if a product ID is any Steam Controller variant static inline int isSteamControllerPID(unsigned short productId) { return (productId == STEAM_CONTROLLER_LEGACY_PID || productId == STEAM_CONTROLLER_WIRED_PID || @@ -44,25 +44,24 @@ static inline int isSteamControllerPID(unsigned short productId) { productId == STEAM_CONTROLLER_V2_BT_PID); } -// Helper function to handle Steam Virtual Gamepad hybrid approach -static inline int getSteamVirtualControllerDetection(SDL_GameController* ctrl, int fallbackControllerType) { +// Steam Virtual Gamepad detection +static inline int getSteamVirtualControllerDetection(SDL_GameController* ctrl, int SDLControllerType) { if (!ctrl) { - return fallbackControllerType; + return SDLControllerType; } SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); if (!joystick || SDL_JoystickGetVendor(joystick) != VALVE_VENDOR_ID) { - return fallbackControllerType; + return SDLControllerType; } unsigned short product = SDL_JoystickGetProduct(joystick); - // Steam Virtual Gamepad: Use the controller type's default glyphs (hybrid approach) if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - return fallbackControllerType; + return SDLControllerType; } - return fallbackControllerType; + return SDLControllerType; } // Generic display names for controller buttons From 62dd5f6898d5cc519cbca4c0853611e42457aa45 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:24:47 -0400 Subject: [PATCH 24/33] swapped Steam Deck and Steam Virtual Gamepad order --- port/src/input.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 53be48ff0d..a7fa00d4a0 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1472,18 +1472,18 @@ const char *inputGetButtonDisplayName(s32 vk) if (vendor == VALVE_VENDOR_ID) { Uint16 product = SDL_JoystickGetProduct(joystick); + // Steam Deck + if (product == STEAM_DECK_BUILTIN_PID) { + iconType = CONTROLLER_ICON_STEAM_DECK; + } // Steam Virtual Gamepad - if (product == STEAM_VIRTUAL_GAMEPAD_PID) { + else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); } // Steam Controller else if (isSteamControllerPID(product)) { iconType = CONTROLLER_ICON_STEAM_CONTROLLER; } - // Steam Deck - else if (product == STEAM_DECK_BUILTIN_PID) { - iconType = CONTROLLER_ICON_STEAM_DECK; - } } } } From f0fc210da8c89cc95030354fc4713e741457ac00 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:41:51 -0400 Subject: [PATCH 25/33] Steam Deck and Steam Controller now uses `getSteamVirtualControllerDetection` this is one final experiment before we drop stick with Steam Virtual Gamepad PID --- port/src/input.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index a7fa00d4a0..6232fd56d1 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1474,15 +1474,11 @@ const char *inputGetButtonDisplayName(s32 vk) // Steam Deck if (product == STEAM_DECK_BUILTIN_PID) { - iconType = CONTROLLER_ICON_STEAM_DECK; - } - // Steam Virtual Gamepad - else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); } // Steam Controller else if (isSteamControllerPID(product)) { - iconType = CONTROLLER_ICON_STEAM_CONTROLLER; + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_CONTROLLER); } } } From bed72f7e6a70178df1fb94eac712e8a1c6d81959 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Mon, 4 Aug 2025 19:58:28 -0400 Subject: [PATCH 26/33] restored Steam Virtual Gamepad PID. it's clear that Steam Virtual Gamepad is the highest priority. for now: we're restoring the original function --- port/src/input.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/port/src/input.c b/port/src/input.c index 6232fd56d1..96b9823042 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1480,6 +1480,10 @@ const char *inputGetButtonDisplayName(s32 vk) else if (isSteamControllerPID(product)) { iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_CONTROLLER); } + // Steam Virtual Gamepad + else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); + } } } } From 6567f38941353fac04741ad49516984288afe014 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:48:50 -0400 Subject: [PATCH 27/33] corrected Switch Joycon prompts layout the Left/Right Joy-Con glyphs has been corrected --- port/src/glyph.c | 68 ++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 5f642c9955..275274d5dc 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -18,15 +18,15 @@ const char *vkJoyDisplayNames[] = { "D-PAD_DOWN", "D-PAD_LEFT", "D-PAD_RIGHT", - "MISC1_BTN", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) - "RIGHT_PADDLE_1", // Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) - "LEFT_PADDLE_1", // Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) - "RIGHT_PADDLE_2", // Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) - "LEFT_PADDLE_2", // Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) + "MISC1_BTN", // Additional button (e.g. Xbox Series X share button, PS5 microphone button, Switch capture button) + "RIGHT_PADDLE_1", // Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1, DualSense Edge RB button, Right Joy-Con SR button) + "LEFT_PADDLE_1", // Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3, DualSense Edge LB button, Left Joy-Con SL button) + "RIGHT_PADDLE_2", // Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2, DualSense Edge right Fn button, Right Joy-Con SR button) + "LEFT_PADDLE_2", // Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4, DualSense Edge left Fn button, Left Joy-Con SL button) "TOUCHPAD_BTN", // PS4/PS5 touchpad button "MISC2_BTN", - "MISC3_BTN", - "MISC4_BTN", + "MISC3_BTN", // Additional button (e.g. Nintendo GameCube Left Trigger click) + "MISC4_BTN", // Additional button (e.g. Nintendo GameCube Right Trigger click) "MISC5_BTN", "MISC6_BTN", "BTN_26", @@ -47,24 +47,24 @@ struct button_override { // Standard button overrides (shared across controllers) static const struct button_override glyph_standard[] = { - { 0, "A_BTN" }, // Bottom face button (A) - { 1, "B_BTN" }, // Right face button (B) - { 2, "X_BTN" }, // Left face button (X) - { 3, "Y_BTN" }, // Top face button (Y) + { 0, "A_BTN" }, // Bottom face button + { 1, "B_BTN" }, // Right face button + { 2, "X_BTN" }, // Left face button + { 3, "Y_BTN" }, // Top face button { 7, "L3_STICK_CLICK" }, // Left stick press (L3) { 8, "R3_STICK_CLICK" }, // Right stick press (R3) { 9, "L1_SHOULDER" }, // Left shoulder (L1) { 10, "R1_SHOULDER" }, // Right shoulder (R1) - { 15, "M1_BTN" }, // M1 button (MISC 1) - { 16, "L4_BTN" }, // Left paddle (L4) - { 17, "L5_BTN" }, // Left paddle (L5) - { 18, "R4_BTN" }, // Right paddle (R4) - { 19, "R5_BTN" }, // Right paddle (R5) - { 21, "M2_BTN" }, // M2 button (MISC 2) - { 22, "M3_BTN" }, // M3 button (MISC 3) - { 23, "M4_BTN" }, // M4 button (MISC 4) - { 30, "L2_TRIG" }, // Left trigger (L2) - { 31, "R2_TRIG" }, // Right trigger (R2) + { 15, "M1_BTN" }, // M1 button + { 16, "L4_BTN" }, // Upper left paddle (L4) + { 17, "L5_BTN" }, // Below left paddle (L5) + { 18, "R4_BTN" }, // Upper right paddle (R4) + { 19, "R5_BTN" }, // Below right paddle (R5) + { 21, "M2_BTN" }, // M2 button + { 22, "M3_BTN" }, // M3 button + { 23, "M4_BTN" }, // M4 button + { 30, "L2_TRIG" }, // Left trigger + { 31, "R2_TRIG" }, // Right trigger }; // Xbox-specific overrides @@ -122,22 +122,22 @@ static const struct button_override ps5_overrides[] = { { 15, "MIC_BTN" }, { 16, "RB_PADDLE" }, // DualSense Edge RB Button { 17, "LB_PADDLE" }, // DualSense Edge LB Button - { 18, "FN_RIGHT_BTN" }, // DualSense Edge right function button - { 19, "FN_LEFT_BTN" }, // DualSense Edge left function button + { 18, "FN_RIGHT_BTN" }, // DualSense Edge right Fn button + { 19, "FN_LEFT_BTN" }, // DualSense Edge left Fn button }; // Nintendo Switch-specific overrides static const struct button_override nintendoswitch_override[] = { - { 4, "MINUS_BTN" }, - { 5, "HOME_BTN" }, - { 6, "PLUS_BTN" }, - { 9, "L_SHOULDER" }, + { 4, "MINUS_BTN" }, + { 5, "HOME_BTN" }, + { 6, "PLUS_BTN" }, + { 9, "L_SHOULDER" }, { 10, "R_SHOULDER" }, - { 15, "CAPTURE_BTN" }, - { 16, "SL_BTN" }, // Left Joy-Con SL - { 17, "SR_BTN" }, // Left Joy-Con SR - { 18, "SL_BTN" }, // Right Joy-Con SL - { 19, "SR_BTN" }, // Right Joy-Con SR + { 15, "CAPTURE_BTN" }, + { 16, "LEFT_SR_BTN" }, // Left Joy-Con SR + { 17, "LEFT_SL_BTN" }, // Left Joy-Con SL + { 18, "RIGHT_SL_BTN" }, // Right Joy-Con SL + { 19, "RIGHT_SR_BTN" }, // Right Joy-Con SR { 30, "ZL_TRIG" }, { 31, "ZR_TRIG" }, }; @@ -152,8 +152,8 @@ static const struct button_override steamdeck_overrides[] = { // Steam Controller-specific overrides static const struct button_override steamcontroller_overrides[] = { { 5, "STEAM_BTN" }, - { 16, "RG_BTN" }, // Steam Controller left grip - { 17, "LG_BTN" }, // Steam Controller right grip + { 16, "RG_BTN" }, // Steam Controller right grip + { 17, "LG_BTN" }, // Steam Controller left grip }; // Nintendo 64-specific overrides (based on NSO N64 controller's button layout) From 7ce1f17f3a3eb6e38bcc2dafa6291bfc283fcb8e Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:12:03 -0400 Subject: [PATCH 28/33] changed document notes --- port/include/glyph.h | 11 ++++--- port/src/glyph.c | 74 +++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index 985b00b500..fc4d74c605 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -64,14 +64,17 @@ static inline int getSteamVirtualControllerDetection(SDL_GameController* ctrl, i return SDLControllerType; } -// Generic display names for controller buttons +// Generic button names for glyphs +// this will cover generalized button names for glyphs based on SDL_GamepadButton extern const char *vkJoyDisplayNames[]; -// Function to get controller-specific button name with fallback to generic +// Controller-specific button glyphs +// this will grab the button glyphs based on the controller type and button index const char *glyphGetControllerButtonName(int controllerType, int buttonIndex); -// Function to replace baked-in button text with dynamic controller bindings -char* glyphInputBindingDetect(char* text, int textSize, const char* placeholder, +// Dynamic glyph input binding detection +// TODO: replace all baked-in button localization text with a dynamic glyph system +char* glyphInputBindingDetect(char* text, int textSize, const char* placeholder, int controllerIndex, int controlKey, int forceController); #endif \ No newline at end of file diff --git a/port/src/glyph.c b/port/src/glyph.c index 275274d5dc..2a1de6fa1d 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -1,6 +1,8 @@ #include #include "glyph.h" +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + // Generic display names for controller buttons (maps to same indices as vkJoyNames) const char *vkJoyDisplayNames[] = { "SOUTH_BTN", // A button (Bottom face button) @@ -38,14 +40,14 @@ const char *vkJoyDisplayNames[] = { }; // Controller-specific overrides +// These are used to map specific controller buttons to Controller-specific glyphs -// Common struct type for button overrides struct button_override { int button_index; const char *name; }; -// Standard button overrides (shared across controllers) +// Standard glyph overrides (shared across controllers) static const struct button_override glyph_standard[] = { { 0, "A_BTN" }, // Bottom face button { 1, "B_BTN" }, // Right face button @@ -68,7 +70,7 @@ static const struct button_override glyph_standard[] = { }; // Xbox-specific overrides -static const struct button_override xbox_specific[] = { +static const struct button_override xbox_overrides[] = { { 5, "XBOX_BTN" }, { 9, "LB_SHOULDER" }, { 10, "RB_SHOULDER" }, @@ -76,7 +78,7 @@ static const struct button_override xbox_specific[] = { { 31, "RT_TRIG" }, }; -// Xbox 360 specific button overrides +// Xbox 360-specific button overrides static const struct button_override xbox360_overrides[] = { { 4, "BACK_BTN" }, { 6, "START_BTN" }, @@ -94,7 +96,7 @@ static const struct button_override xboxone_overrides[] = { }; // PlayStation-specific overrides -static const struct button_override playstation_specific[] = { +static const struct button_override playstation_overrides[] = { { 0, "CROSS_BTN" }, { 1, "CIRCLE_BTN" }, { 2, "SQUARE_BTN" }, @@ -127,7 +129,7 @@ static const struct button_override ps5_overrides[] = { }; // Nintendo Switch-specific overrides -static const struct button_override nintendoswitch_override[] = { +static const struct button_override nintendoswitch_overrides[] = { { 4, "MINUS_BTN" }, { 5, "HOME_BTN" }, { 6, "PLUS_BTN" }, @@ -168,17 +170,17 @@ static const struct button_override nintendo64_overrides[] = { { 31, "Z_BTN" }, }; -// Function to search an override for a specific button index +// Function to override a specific button index static const char* searchOverrides(const struct button_override* overrides, int count, int buttonIndex) { - for (int i = 0; i < count; i++) { - if (overrides[i].button_index == buttonIndex) { - return overrides[i].name; + for (const struct button_override* override = overrides; override < overrides + count; override++) { + if (override->button_index == buttonIndex) { + return override->name; } } return NULL; } -// Function to get controller-specific button names +// Function to search and provide Controller-specific button types const char *glyphGetControllerButtonName(int controllerType, int buttonIndex) { const char *result = NULL; @@ -186,91 +188,91 @@ const char *glyphGetControllerButtonName(int controllerType, int buttonIndex) switch (controllerType) { case CONTROLLER_ICON_XBOX360: // Xbox 360-specific overrides - result = searchOverrides(xbox360_overrides, sizeof(xbox360_overrides) / sizeof(xbox360_overrides[0]), buttonIndex); + result = searchOverrides(xbox360_overrides, ARRAY_SIZE(xbox360_overrides), buttonIndex); if (result) return result; // Xbox overrides - result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + result = searchOverrides(xbox_overrides, ARRAY_SIZE(xbox_overrides), buttonIndex); if (result) return result; // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_STEAM_CONTROLLER: // Steam Controller-specific overrides - result = searchOverrides(steamcontroller_overrides, sizeof(steamcontroller_overrides) / sizeof(steamcontroller_overrides[0]), buttonIndex); + result = searchOverrides(steamcontroller_overrides, ARRAY_SIZE(steamcontroller_overrides), buttonIndex); if (result) return result; // Xbox overrides (Shoulders and triggers) - result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + result = searchOverrides(xbox_overrides, ARRAY_SIZE(xbox_overrides), buttonIndex); if (result) return result; // Glyph standard (Face buttons) if (buttonIndex >= 0 && buttonIndex <= 3) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_XBOXONE: // Xbox One/Series X|S-specific overrides - result = searchOverrides(xboxone_overrides, sizeof(xboxone_overrides) / sizeof(xboxone_overrides[0]), buttonIndex); + result = searchOverrides(xboxone_overrides, ARRAY_SIZE(xboxone_overrides), buttonIndex); if (result) return result; // Xbox overrides - result = searchOverrides(xbox_specific, sizeof(xbox_specific) / sizeof(xbox_specific[0]), buttonIndex); + result = searchOverrides(xbox_overrides, ARRAY_SIZE(xbox_overrides), buttonIndex); if (result) return result; // Glyph standard (Face Button only) if (buttonIndex >= 0 && buttonIndex <= 3) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_PS3: // PS3-specific overrides - result = searchOverrides(ps3_overrides, sizeof(ps3_overrides) / sizeof(ps3_overrides[0]), buttonIndex); + result = searchOverrides(ps3_overrides, ARRAY_SIZE(ps3_overrides), buttonIndex); if (result) return result; // PlayStation overrides - result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + result = searchOverrides(playstation_overrides, ARRAY_SIZE(playstation_overrides), buttonIndex); if (result) return result; // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_PS4: // PS4-specific overrides - result = searchOverrides(ps4_overrides, sizeof(ps4_overrides) / sizeof(ps4_overrides[0]), buttonIndex); + result = searchOverrides(ps4_overrides, ARRAY_SIZE(ps4_overrides), buttonIndex); if (result) return result; // PlayStation overrides - result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + result = searchOverrides(playstation_overrides, ARRAY_SIZE(playstation_overrides), buttonIndex); if (result) return result; // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_PS5: // PS5-specific overrides - result = searchOverrides(ps5_overrides, sizeof(ps5_overrides) / sizeof(ps5_overrides[0]), buttonIndex); + result = searchOverrides(ps5_overrides, ARRAY_SIZE(ps5_overrides), buttonIndex); if (result) return result; // PlayStation overrides - result = searchOverrides(playstation_specific, sizeof(playstation_specific) / sizeof(playstation_specific[0]), buttonIndex); + result = searchOverrides(playstation_overrides, ARRAY_SIZE(playstation_overrides), buttonIndex); if (result) return result; // Glyph standard (Face, Shoulders, Triggers only) if ((buttonIndex >= 0 && buttonIndex <= 10) || (buttonIndex >= 30 && buttonIndex <= 31)) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_NINTENDO_SWITCH: // Nintendo Switch specific overrides - result = searchOverrides(nintendoswitch_override, sizeof(nintendoswitch_override) / sizeof(nintendoswitch_override[0]), buttonIndex); + result = searchOverrides(nintendoswitch_overrides, ARRAY_SIZE(nintendoswitch_overrides), buttonIndex); if (result) return result; // Glyph standard (swapped Face Buttons positions) if (buttonIndex >= 0 && buttonIndex <= 3) { @@ -281,34 +283,34 @@ const char *glyphGetControllerButtonName(int controllerType, int buttonIndex) case 2: mappedIndex = 3; break; // Y (Left face button) case 3: mappedIndex = 2; break; // X (Top face button) } - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), mappedIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), mappedIndex); if (result) return result; } break; case CONTROLLER_ICON_NINTENDO_64: // Nintendo 64-specific overrides - result = searchOverrides(nintendo64_overrides, sizeof(nintendo64_overrides) / sizeof(nintendo64_overrides[0]), buttonIndex); + result = searchOverrides(nintendo64_overrides, ARRAY_SIZE(nintendo64_overrides), buttonIndex); if (result) return result; // Nintendo Switch specific overrides (for NSO N64 controller's Home and Capture buttons) if (buttonIndex == 5 || buttonIndex == 15) { - result = searchOverrides(nintendoswitch_override, sizeof(nintendoswitch_override) / sizeof(nintendoswitch_override[0]), buttonIndex); + result = searchOverrides(nintendoswitch_overrides, ARRAY_SIZE(nintendoswitch_overrides), buttonIndex); if (result) return result; } // Glyph standard (N64 face buttons) if (buttonIndex >= 0 && buttonIndex <= 1) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; case CONTROLLER_ICON_STEAM_DECK: // Steam Deck-specific overrides - result = searchOverrides(steamdeck_overrides, sizeof(steamdeck_overrides) / sizeof(steamdeck_overrides[0]), buttonIndex); + result = searchOverrides(steamdeck_overrides, ARRAY_SIZE(steamdeck_overrides), buttonIndex); if (result) return result; // Glyph standard if ((buttonIndex >= 0 && buttonIndex <= 19) || (buttonIndex >= 30 && buttonIndex <= 31)) { - result = searchOverrides(glyph_standard, sizeof(glyph_standard) / sizeof(glyph_standard[0]), buttonIndex); + result = searchOverrides(glyph_standard, ARRAY_SIZE(glyph_standard), buttonIndex); if (result) return result; } break; From 6a29805aed50300ca4509e3295332c120121c729 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Tue, 5 Aug 2025 17:23:07 -0400 Subject: [PATCH 29/33] fixed Switch Joy-Con SL/SR position layout --- port/src/glyph.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/port/src/glyph.c b/port/src/glyph.c index 2a1de6fa1d..49090fc5a5 100644 --- a/port/src/glyph.c +++ b/port/src/glyph.c @@ -124,8 +124,8 @@ static const struct button_override ps5_overrides[] = { { 15, "MIC_BTN" }, { 16, "RB_PADDLE" }, // DualSense Edge RB Button { 17, "LB_PADDLE" }, // DualSense Edge LB Button - { 18, "FN_RIGHT_BTN" }, // DualSense Edge right Fn button - { 19, "FN_LEFT_BTN" }, // DualSense Edge left Fn button + { 18, "RIGHT_FN_BTN" }, // DualSense Edge right Fn button + { 19, "LEFT_FN_BTN" }, // DualSense Edge left Fn button }; // Nintendo Switch-specific overrides @@ -136,10 +136,10 @@ static const struct button_override nintendoswitch_overrides[] = { { 9, "L_SHOULDER" }, { 10, "R_SHOULDER" }, { 15, "CAPTURE_BTN" }, - { 16, "LEFT_SR_BTN" }, // Left Joy-Con SR + { 16, "RIGHT_SR_BTN" }, // Right Joy-Con SR { 17, "LEFT_SL_BTN" }, // Left Joy-Con SL { 18, "RIGHT_SL_BTN" }, // Right Joy-Con SL - { 19, "RIGHT_SR_BTN" }, // Right Joy-Con SR + { 19, "LEFT_SR_BTN" }, // Left Joy-Con SR { 30, "ZL_TRIG" }, { 31, "ZR_TRIG" }, }; From 74351c02edc972455b4965521f498183d4a48208 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:23:37 -0500 Subject: [PATCH 30/33] slight change to how Controller Icon generic is handled --- port/src/input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/port/src/input.c b/port/src/input.c index 96b9823042..13114acd3b 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1474,11 +1474,11 @@ const char *inputGetButtonDisplayName(s32 vk) // Steam Deck if (product == STEAM_DECK_BUILTIN_PID) { - iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); + iconType = CONTROLLER_ICON_STEAM_DECK; } // Steam Controller else if (isSteamControllerPID(product)) { - iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_CONTROLLER); + iconType = CONTROLLER_ICON_STEAM_CONTROLLER; } // Steam Virtual Gamepad else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { From 0106c107d7b89b55e6af4634d695dfa32e9d2e14 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:29:38 -0500 Subject: [PATCH 31/33] reaplce Joystick with GameControllerVendor/Product --- port/include/glyph.h | 18 ++++++++++++++---- port/src/input.c | 32 ++++++++++++++------------------ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/port/include/glyph.h b/port/include/glyph.h index fc4d74c605..3d5acf46f3 100644 --- a/port/include/glyph.h +++ b/port/include/glyph.h @@ -33,7 +33,7 @@ typedef enum { #define STEAM_VIRTUAL_GAMEPAD_PID 0x11ff // Steam Virtual Gamepad #define STEAM_DECK_BUILTIN_PID 0x1205 // Valve Steam Deck Builtin -// Check if a product ID is any Steam Controller variant +// Check if a product ID is any Steam Controller (2015) variant static inline int isSteamControllerPID(unsigned short productId) { return (productId == STEAM_CONTROLLER_LEGACY_PID || productId == STEAM_CONTROLLER_WIRED_PID || @@ -50,17 +50,27 @@ static inline int getSteamVirtualControllerDetection(SDL_GameController* ctrl, i return SDLControllerType; } - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (!joystick || SDL_JoystickGetVendor(joystick) != VALVE_VENDOR_ID) { + if (SDL_GameControllerGetVendor(ctrl) != VALVE_VENDOR_ID) { return SDLControllerType; } - unsigned short product = SDL_JoystickGetProduct(joystick); + unsigned short product = SDL_GameControllerGetProduct(ctrl); + // Steam Virtual Gamepad - pass through the underlying controller type if (product == STEAM_VIRTUAL_GAMEPAD_PID) { return SDLControllerType; } + // Steam Deck + if (product == STEAM_DECK_BUILTIN_PID) { + return CONTROLLER_ICON_STEAM_DECK; + } + + // Steam Controller (2015) + if (isSteamControllerPID(product)) { + return CONTROLLER_ICON_STEAM_CONTROLLER; + } + return SDLControllerType; } diff --git a/port/src/input.c b/port/src/input.c index 13114acd3b..d88021c507 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1466,24 +1466,20 @@ const char *inputGetButtonDisplayName(s32 vk) { int iconType = CONTROLLER_ICON_GENERIC; if (ctrl) { - SDL_Joystick *joystick = SDL_GameControllerGetJoystick(ctrl); - if (joystick) { - Uint16 vendor = SDL_JoystickGetVendor(joystick); - if (vendor == VALVE_VENDOR_ID) { - Uint16 product = SDL_JoystickGetProduct(joystick); - - // Steam Deck - if (product == STEAM_DECK_BUILTIN_PID) { - iconType = CONTROLLER_ICON_STEAM_DECK; - } - // Steam Controller - else if (isSteamControllerPID(product)) { - iconType = CONTROLLER_ICON_STEAM_CONTROLLER; - } - // Steam Virtual Gamepad - else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); - } + if (SDL_GameControllerGetVendor(ctrl) == VALVE_VENDOR_ID) { + Uint16 product = SDL_GameControllerGetProduct(ctrl); + + // Steam Deck + if (product == STEAM_DECK_BUILTIN_PID) { + iconType = CONTROLLER_ICON_STEAM_DECK; + } + // Steam Controller + else if (isSteamControllerPID(product)) { + iconType = CONTROLLER_ICON_STEAM_CONTROLLER; + } + // Steam Virtual Gamepad + else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); } } } From dbcdb0d2e34fa0fa48c153a6becb1c7cb9c005f2 Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:51:26 -0500 Subject: [PATCH 32/33] experimenting with Steam Virtual Gamepad, part 2 temporarily switch to Generic Prompts on Steam Deck's under Game Mode. --- port/src/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/src/input.c b/port/src/input.c index d88021c507..7df6c749d4 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1479,7 +1479,7 @@ const char *inputGetButtonDisplayName(s32 vk) } // Steam Virtual Gamepad else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_GENERIC); } } } From ae2db335502670bf4c05df9468965a49e607d6ed Mon Sep 17 00:00:00 2001 From: AL2009man <67606569+AL2009man@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:38:28 -0500 Subject: [PATCH 33/33] Revert "experimenting with Steam Virtual Gamepad, part 2" This reverts commit dbcdb0d2e34fa0fa48c153a6becb1c7cb9c005f2. --- port/src/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/port/src/input.c b/port/src/input.c index 7df6c749d4..d88021c507 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -1479,7 +1479,7 @@ const char *inputGetButtonDisplayName(s32 vk) } // Steam Virtual Gamepad else if (product == STEAM_VIRTUAL_GAMEPAD_PID) { - iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_GENERIC); + iconType = getSteamVirtualControllerDetection(ctrl, CONTROLLER_ICON_STEAM_DECK); } } }