commit 13f76d361a18e4b0f083ce1cca4c1d05fd9435bb
Author: Michael Day <contact@michaelcday.com>
AuthorDate: Sun Aug 6 23:33:24 2023 -0400
Commit: Turo Lamminen <turol@users.noreply.github.com>
CommitDate: Wed Aug 23 11:42:50 2023 +0300
Show real button names for popular gamepads
---
src/i_joystick.c | 5 +
src/m_config.c | 6 +
src/setup/joystick.c | 6 +
src/setup/joystick.h | 1 +
src/setup/txt_joybinput.c | 282 +++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 299 insertions(+), 1 deletion(-)
diff --git a/src/i_joystick.c b/src/i_joystick.c
index eb471750..f2b6e6f9 100644
--- a/src/i_joystick.c
+++ b/src/i_joystick.c
@@ -49,6 +49,9 @@ static int usejoystick = 0;
// Use SDL_gamecontroller interface for the selected device
static int use_gamepad = 0;
+// SDL_GameControllerType of gamepad
+static int gamepad_type = 0;
+
// SDL GUID and index of the joystick to use.
static char *joystick_guid = "";
static int joystick_index = -1;
@@ -194,6 +197,7 @@ void I_InitGamepad(void)
}
joystick_index = index;
+ gamepad_type = SDL_GameControllerTypeForIndex(index);
if (strcmp(joystick_guid, ""))
{
@@ -633,6 +637,7 @@ void I_BindJoystickVariables(void)
M_BindIntVariable("use_joystick", &usejoystick);
M_BindIntVariable("use_gamepad", &use_gamepad);
+ M_BindIntVariable("gamepad_type", &gamepad_type);
M_BindStringVariable("joystick_guid", &joystick_guid);
M_BindIntVariable("joystick_index", &joystick_index);
M_BindIntVariable("joystick_x_axis", &joystick_x_axis);
diff --git a/src/m_config.c b/src/m_config.c
index c38d5989..109601b0 100644
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -1376,6 +1376,12 @@ static default_t extra_defaults_list[] =
CONFIG_VARIABLE_INT(use_gamepad),
+ //!
+ // Stores the SDL_GameControllerType of the last configured gamepad.
+ //
+
+ CONFIG_VARIABLE_INT(gamepad_type),
+
//!
// Joystick virtual button to make the player strafe left.
//
diff --git a/src/setup/joystick.c b/src/setup/joystick.c
index 72886d59..dd24448c 100644
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -599,6 +599,9 @@ static const known_joystick_t known_joysticks[] =
// Use SDL_GameController interface
int use_gamepad = 0;
+// SDL_GameControllerType of gamepad
+int gamepad_type = 0;
+
// Based on Unity Doom mapping
static const joystick_config_t modern_gamepad[] =
{
@@ -980,6 +983,7 @@ static int CalibrationEventCallback(SDL_Event *event, void *user_data)
{
usejoystick = 1;
use_gamepad = 1;
+ gamepad_type = SDL_GameControllerTypeForIndex(joystick_index);
LoadConfigurationSet(empty_defaults);
GetGamepadDefaultConfig();
TXT_CloseWindow(calibration_window);
@@ -990,6 +994,7 @@ static int CalibrationEventCallback(SDL_Event *event, void *user_data)
// In the first "center" stage, we're just trying to work out which
// joystick is being configured and which button the user is pressing.
usejoystick = 1;
+ gamepad_type = SDL_CONTROLLER_TYPE_UNKNOWN;
calibrate_button = event->jbutton.button;
// If the joystick is a known one, auto-load default
@@ -1205,6 +1210,7 @@ void BindJoystickVariables(void)
M_BindIntVariable("use_joystick", &usejoystick);
M_BindIntVariable("use_gamepad", &use_gamepad);
+ M_BindIntVariable("gamepad_type", &gamepad_type);
M_BindStringVariable("joystick_guid", &joystick_guid);
M_BindIntVariable("joystick_index", &joystick_index);
M_BindIntVariable("joystick_x_axis", &joystick_x_axis);
diff --git a/src/setup/joystick.h b/src/setup/joystick.h
index 3a9d1705..dd17b7d9 100644
--- a/src/setup/joystick.h
+++ b/src/setup/joystick.h
@@ -22,6 +22,7 @@
extern int joystick_index;
extern int joystick_physical_buttons[NUM_VIRTUAL_BUTTONS];
extern int use_gamepad;
+extern int gamepad_type;
void ConfigJoystick(void *widget, void *user_data);
diff --git a/src/setup/txt_joybinput.c b/src/setup/txt_joybinput.c
index ca469731..6321a066 100644
--- a/src/setup/txt_joybinput.c
+++ b/src/setup/txt_joybinput.c
@@ -60,6 +60,199 @@ static int *all_joystick_buttons[NUM_VIRTUAL_BUTTONS] =
&joybautomap,
};
+// For indirection so that we're not dependent on item ordering in the
+// SDL_GameControllerButton enum.
+static const int gamepad_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ SDL_CONTROLLER_BUTTON_A,
+ SDL_CONTROLLER_BUTTON_B,
+ SDL_CONTROLLER_BUTTON_X,
+ SDL_CONTROLLER_BUTTON_Y,
+ SDL_CONTROLLER_BUTTON_BACK,
+ SDL_CONTROLLER_BUTTON_GUIDE,
+ SDL_CONTROLLER_BUTTON_START,
+ SDL_CONTROLLER_BUTTON_LEFTSTICK,
+ SDL_CONTROLLER_BUTTON_RIGHTSTICK,
+ SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
+ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
+ SDL_CONTROLLER_BUTTON_DPAD_UP,
+ SDL_CONTROLLER_BUTTON_DPAD_DOWN,
+ SDL_CONTROLLER_BUTTON_DPAD_LEFT,
+ SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
+ SDL_CONTROLLER_BUTTON_MISC1,
+ SDL_CONTROLLER_BUTTON_PADDLE1,
+ SDL_CONTROLLER_BUTTON_PADDLE2,
+ SDL_CONTROLLER_BUTTON_PADDLE3,
+ SDL_CONTROLLER_BUTTON_PADDLE4,
+ SDL_CONTROLLER_BUTTON_TOUCHPAD,
+ GAMEPAD_BUTTON_TRIGGERLEFT,
+ GAMEPAD_BUTTON_TRIGGERRIGHT,
+};
+
+// Items in the following button lists are ordered according to gamepad_buttons
+// above.
+static const char *xbox360_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "A",
+ "B",
+ "X",
+ "Y",
+ "BACK",
+ "GUIDE",
+ "START",
+ "LSB",
+ "RSB",
+ "LB",
+ "RB",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "LT",
+ "RT",
+};
+
+static const char *xboxone_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "A",
+ "B",
+ "X",
+ "Y",
+ "VIEW",
+ "XBOX",
+ "MENU",
+ "LSB",
+ "RSB",
+ "LB",
+ "RB",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "PROFILE",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "",
+ "LT",
+ "RT",
+};
+
+static const char *ps3_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "X",
+ "CIRCLE",
+ "SQUARE",
+ "TRIANGLE",
+ "SELECT",
+ "PS",
+ "START",
+ "L3",
+ "R3",
+ "L1",
+ "R1",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "L2",
+ "R2",
+};
+
+static const char *ps4_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "X",
+ "CIRCLE",
+ "SQUARE",
+ "TRIANGLE",
+ "SHARE",
+ "PS",
+ "OPTIONS",
+ "L3",
+ "R3",
+ "L1",
+ "R1",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "TOUCH",
+ "L2",
+ "R2",
+};
+
+static const char *ps5_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "X",
+ "CIRCLE",
+ "SQUARE",
+ "TRIANGLE",
+ "SHARE",
+ "PS",
+ "OPTIONS",
+ "L3",
+ "R3",
+ "L1",
+ "R1",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "MUTE",
+ "",
+ "",
+ "",
+ "",
+ "TOUCH",
+ "L2",
+ "R2",
+};
+
+static const char *switchpro_buttons[GAMEPAD_BUTTON_MAX] =
+{
+ "B",
+ "A",
+ "Y",
+ "X",
+ "MINUS",
+ "HOME",
+ "PLUS",
+ "LSB",
+ "RSB",
+ "L",
+ "R",
+ "DPAD U",
+ "DPAD D",
+ "DPAD L",
+ "DPAD R",
+ "CAPTURE",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "ZL",
+ "ZR",
+};
+
static int PhysicalForVirtualButton(int vbutton)
{
if (vbutton < NUM_VIRTUAL_BUTTONS)
@@ -381,6 +574,93 @@ static void TXT_JoystickInputDrawer(TXT_UNCAST_ARG(joystick_input))
}
}
+static int GetGamepadButtonIndex(int button)
+{
+ int i;
+
+ for (i = 0; i < arrlen(gamepad_buttons); ++i)
+ {
+ if (button == gamepad_buttons[i])
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static void GetGamepadButtonDescription(int vbutton, char *buf, size_t buf_len)
+{
+ int index;
+
+ index = GetGamepadButtonIndex(PhysicalForVirtualButton(vbutton));
+
+ if (index < 0)
+ {
+ M_StringCopy(buf, "(unknown)", buf_len);
+ return;
+ }
+
+ switch (gamepad_type)
+ {
+ case SDL_CONTROLLER_TYPE_XBOX360:
+ M_snprintf(buf, buf_len, "%s", xbox360_buttons[index]);
+ break;
+
+ case SDL_CONTROLLER_TYPE_XBOXONE:
+ M_snprintf(buf, buf_len, "%s", xboxone_buttons[index]);
+ break;
+
+ case SDL_CONTROLLER_TYPE_PS3:
+ M_snprintf(buf, buf_len, "%s", ps3_buttons[index]);
+ break;
+
+ case SDL_CONTROLLER_TYPE_PS4:
+ M_snprintf(buf, buf_len, "%s", ps4_buttons[index]);
+ break;
+
+ case SDL_CONTROLLER_TYPE_PS5:
+ M_snprintf(buf, buf_len, "%s", ps5_buttons[index]);
+ break;
+
+ case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
+ M_snprintf(buf, buf_len, "%s", switchpro_buttons[index]);
+ break;
+
+ default:
+ M_snprintf(buf, buf_len, "BUTTON #%i",
+ PhysicalForVirtualButton(vbutton) + 1);
+ break;
+ }
+}
+
+static void TXT_GamepadInputDrawer(TXT_UNCAST_ARG(joystick_input))
+{
+ TXT_CAST_ARG(txt_joystick_input_t, joystick_input);
+ char buf[20]; // Need to fit "BUTTON #XX"
+ int i;
+
+ if (*joystick_input->variable < 0)
+ {
+ M_StringCopy(buf, "(none)", sizeof(buf));
+ }
+ else
+ {
+ GetGamepadButtonDescription(*joystick_input->variable, buf,
+ sizeof(buf));
+ }
+
+ TXT_SetWidgetBG(joystick_input);
+ TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
+
+ TXT_DrawString(buf);
+
+ for (i = TXT_UTF8_Strlen(buf); i < JOYSTICK_INPUT_WIDTH; ++i)
+ {
+ TXT_DrawString(" ");
+ }
+}
+
static void TXT_JoystickInputDestructor(TXT_UNCAST_ARG(joystick_input))
{
}
@@ -466,7 +746,7 @@ txt_widget_class_t txt_gamepad_input_class =
{
TXT_AlwaysSelectable,
TXT_JoystickInputSizeCalc,
- TXT_JoystickInputDrawer,
+ TXT_GamepadInputDrawer,
TXT_GamepadInputKeyPress,
TXT_JoystickInputDestructor,
TXT_GamepadInputMousePress,