summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/osd/modules/input/input_sdl.cpp6
-rw-r--r--src/osd/modules/input/input_xinput.cpp124
2 files changed, 102 insertions, 28 deletions
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 0f7ece4bdf1..9a93177d521 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -1259,7 +1259,7 @@ public:
#endif
// add axes
- std::tuple<SDL_GameControllerAxis, input_item_id, bool> axes[]{
+ std::tuple<SDL_GameControllerAxis, input_item_id, bool> const axes[]{
{ SDL_CONTROLLER_AXIS_LEFTX, ITEM_ID_XAXIS, false },
{ SDL_CONTROLLER_AXIS_LEFTY, ITEM_ID_YAXIS, false },
{ SDL_CONTROLLER_AXIS_RIGHTX, ITEM_ID_ZAXIS, false },
@@ -1299,7 +1299,7 @@ public:
}
// add automatically numbered buttons
- std::pair<SDL_GameControllerButton, SDL_GameControllerAxis> numberedbuttons[]{
+ std::pair<SDL_GameControllerButton, SDL_GameControllerAxis> const numberedbuttons[]{
{ SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_AXIS_INVALID },
{ SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_AXIS_INVALID },
{ SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_AXIS_INVALID },
@@ -1386,7 +1386,7 @@ public:
}
// add buttons with fixed item IDs
- std::pair<SDL_GameControllerButton, input_item_id> fixedbuttons[]{
+ std::pair<SDL_GameControllerButton, input_item_id> const fixedbuttons[]{
{ SDL_CONTROLLER_BUTTON_BACK, ITEM_ID_SELECT },
{ SDL_CONTROLLER_BUTTON_START, ITEM_ID_START },
{ SDL_CONTROLLER_BUTTON_DPAD_UP, ITEM_ID_HAT1UP },
diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp
index 27aefa29d02..d5b7614478b 100644
--- a/src/osd/modules/input/input_xinput.cpp
+++ b/src/osd/modules/input/input_xinput.cpp
@@ -94,7 +94,7 @@ layouts corresponding to the latter two arcade stick layouts, with the
rightmost column on the shoulder buttons. Examples of face button
layouts:
-Mad Catz Street Fighter IV FightPad, PowerA FUSION Wired FightPad
+Hori Fighting Commander OCTA, Mad Catz Street Fighter IV FightPad, PowerA FUSION Wired FightPad
X Y RB
A B RT
@@ -121,6 +121,18 @@ A U B
L R
Y D X
+
+Drum kits also have multiple layouts.
+
+Rock Band:
+B Y X A
+ LB
+
+Guitar Hero:
+ Y RB
+A X B
+ LB
+
*/
#include "modules/osdmodule.h"
@@ -137,7 +149,6 @@ Y D X
#include <algorithm>
#include <cstdint>
#include <string>
-#include <tuple>
#include <utility>
@@ -172,6 +183,14 @@ char const *const AXIS_NAMES_FLIGHT_STICK[]{
"Rudder",
"Throttle" };
+char const *const AXIS_NAMES_GUITAR[]{
+ "LSX",
+ "LSY",
+ "Whammy Bar",
+ "Orientation",
+ "Pickup Selector",
+ "RT" };
+
input_item_id const AXIS_IDS_GAMEPAD[]{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
@@ -188,7 +207,7 @@ input_item_id const AXIS_IDS_FLIGHT_STICK[]{
ITEM_ID_RZAXIS,
ITEM_ID_ZAXIS };
-const char *const HAT_NAMES_GAMEPAD[]{
+char const *const HAT_NAMES_GAMEPAD[]{
"D-pad Up",
"D-pad Down",
"D-pad Left",
@@ -198,7 +217,7 @@ const char *const HAT_NAMES_GAMEPAD[]{
"POV Hat Left",
"POV Hat Right" };
-const char *const HAT_NAMES_ARCADE_STICK[]{
+char const *const HAT_NAMES_ARCADE_STICK[]{
"Joystick Up",
"Joystick Down",
"Joystick Left",
@@ -208,6 +227,42 @@ const char *const HAT_NAMES_ARCADE_STICK[]{
nullptr,
nullptr };
+char const *const BUTTON_NAMES_GAMEPAD[]{
+ "A",
+ "B",
+ "X",
+ "Y",
+ "LT",
+ "RT",
+ "LB",
+ "RB",
+ "LSB",
+ "RSB" };
+
+char const *const BUTTON_NAMES_GUITAR[]{
+ "Fret 1",
+ "Fret 2",
+ "Fret 3",
+ "Fret 4",
+ nullptr,
+ nullptr,
+ "Fret 5",
+ "RB",
+ "LSB", // supposedly "fret modifier" - how does this work?
+ "RSB" };
+
+char const *const BUTTON_NAMES_DRUMKIT[]{
+ "Green", // floor tom
+ "Red", // snare
+ "Blue", // low tom
+ "Yellow", // Rock Band high tom, Guitar Hero hi-hat
+ nullptr,
+ nullptr,
+ "Orange", // Guitar Hero crash cymbal
+ "Bass Drum",
+ "LSB",
+ "RSB" };
+
//============================================================
// xinput_joystick_device
@@ -369,7 +424,7 @@ void xinput_joystick_device::reset()
void xinput_joystick_device::configure()
{
// TODO: don't add axes not present in capabilities
- // TODO: proper support for dance mat, guitar and drum kit controllers
+ // TODO: proper support for dance mat controllers
// default characteristics for a gamepad
char const *type_name = "unsupported";
@@ -377,9 +432,12 @@ void xinput_joystick_device::configure()
bool lt_rt_button = false;
bool lt_rt_fullaxis = false;
bool rstick_hat = false;
+ bool button_order_guitar = false;
+ bool button_order_drumkit = false;
char const *const *axis_names = AXIS_NAMES_GAMEPAD;
input_item_id const *axis_ids = AXIS_IDS_GAMEPAD;
char const *const *hat_names = HAT_NAMES_GAMEPAD;
+ char const *const *button_names = BUTTON_NAMES_GAMEPAD;
// consider the device type to decide how to map controls
switch (m_capabilities.Type)
@@ -417,9 +475,14 @@ void xinput_joystick_device::configure()
case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
case XINPUT_DEVSUBTYPE_GUITAR_BASS:
subtype_name = "guitar";
+ button_order_guitar = true;
+ axis_names = AXIS_NAMES_GUITAR;
+ button_names = BUTTON_NAMES_GUITAR;
break;
case XINPUT_DEVSUBTYPE_DRUM_KIT:
subtype_name = "drum kit";
+ button_order_drumkit = true;
+ button_names = BUTTON_NAMES_DRUMKIT;
break;
case XINPUT_DEVSUBTYPE_ARCADE_PAD:
subtype_name = "arcade pad";
@@ -439,14 +502,14 @@ void xinput_joystick_device::configure()
// log some diagnostic information
osd_printf_verbose(
- "Configuring XInput player %d type 0x%02X (%s) sub type 0x%02X (%s)\n",
+ "XInput: Configuring player %d type 0x%02X (%s) sub type 0x%02X (%s).\n",
m_player_index + 1,
m_capabilities.Type,
type_name,
m_capabilities.SubType,
subtype_name);
osd_printf_verbose(
- "XInput switch capabilities A=%d B=%d X=%d Y=%d LB=%d RB=%d LSB=%d RSB=%d Start=%d Back=%d Up=%d Down=%d Left=%d Right=%d\n",
+ "XInput: Switch capabilities A=%d B=%d X=%d Y=%d LB=%d RB=%d LSB=%d RSB=%d Start=%d Back=%d Up=%d Down=%d Left=%d Right=%d.\n",
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 1 : 0,
@@ -462,7 +525,7 @@ void xinput_joystick_device::configure()
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? 1 : 0);
osd_printf_verbose(
- "XInput axis capabilities LT=0x%02X (%d-bit%s) RT=0x%02X (%d-bit%s) LSX=0x%04X (%d-bit%s) LSY=0x%04X (%d-bit%s) RSX=0x%04X (%d-bit%s) RSY=0x%04X (%d-bit%s)\n",
+ "XInput: Axis capabilities LT=0x%02X (%d-bit%s) RT=0x%02X (%d-bit%s) LSX=0x%04X (%d-bit%s) LSY=0x%04X (%d-bit%s) RSX=0x%04X (%d-bit%s) RSY=0x%04X (%d-bit%s).\n",
m_capabilities.Gamepad.bLeftTrigger,
count_leading_ones_32(uint32_t(m_capabilities.Gamepad.bLeftTrigger) << 24),
ltcap_bad ? ", invalid" : "",
@@ -487,13 +550,13 @@ void xinput_joystick_device::configure()
if (ltcap_bad || rtcap_bad || lsxcap_bad || lsycap_bad || rsxcap_bad || rsycap_bad)
{
// Retro-Bit Sega Saturn Control Pad reports garbage for axis resolutions and absence of several buttons
- osd_printf_verbose("Ignoring invalid XInput capabilities (invalid axis resolution)\n");
+ osd_printf_verbose("XInput: Ignoring invalid capabilities (invalid axis resolution).\n");
ignore_caps = true;
}
else if (!m_capabilities.Gamepad.wButtons && !m_capabilities.Gamepad.bLeftTrigger && !m_capabilities.Gamepad.bRightTrigger && !m_capabilities.Gamepad.sThumbLX && !m_capabilities.Gamepad.sThumbLY && !m_capabilities.Gamepad.sThumbRX && !m_capabilities.Gamepad.sThumbRY)
{
// 8BitDo SN30 Pro V1 reports no controls at all, which would be completely useless
- osd_printf_verbose("Ignoring invalid XInput capabilities (no controls reported)\n");
+ osd_printf_verbose("XInput: Ignoring invalid capabilities (no controls reported).\n");
ignore_caps = true;
}
if (ignore_caps)
@@ -553,27 +616,38 @@ void xinput_joystick_device::configure()
}
// add buttons
- std::tuple<unsigned, char const *, bool> const button_caps[]{
- { SWITCH_A, "A", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0 },
- { SWITCH_B, "B", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0 },
- { SWITCH_X, "X", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0 },
- { SWITCH_Y, "Y", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0 },
- { SWITCH_LT, "LT", lt_rt_button && m_capabilities.Gamepad.bLeftTrigger },
- { SWITCH_RT, "RT", lt_rt_button && m_capabilities.Gamepad.bRightTrigger },
- { SWITCH_LB, "LB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0 },
- { SWITCH_RB, "RB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0 },
- { SWITCH_LSB, "LSB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0 },
- { SWITCH_RSB, "RSB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0 } };
+ std::pair<unsigned, bool> button_caps[]{
+ { SWITCH_A, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0 },
+ { SWITCH_B, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0 },
+ { SWITCH_X, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0 },
+ { SWITCH_Y, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0 },
+ { SWITCH_LT, lt_rt_button && m_capabilities.Gamepad.bLeftTrigger },
+ { SWITCH_RT, lt_rt_button && m_capabilities.Gamepad.bRightTrigger },
+ { SWITCH_LB, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0 },
+ { SWITCH_RB, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0 },
+ { SWITCH_LSB, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0 },
+ { SWITCH_RSB, (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0 } };
+ if (button_order_guitar)
+ {
+ using std::swap;
+ swap(button_caps[2], button_caps[3]);
+ }
+ if (button_order_drumkit)
+ {
+ using std::swap;
+ swap(button_caps[6], button_caps[7]);
+ }
input_item_id button_id = ITEM_ID_BUTTON1;
- for (auto [i, name, supported] : button_caps)
+ for (unsigned i = 0; std::size(button_caps) > i; ++i)
{
+ auto const [offset, supported] = button_caps[i];
if (supported)
{
device()->add_item(
- name,
+ button_names[i],
button_id++,
generic_button_get_state<uint8_t>,
- &m_switches[i]);
+ &m_switches[offset]);
}
}
@@ -670,7 +744,7 @@ int xinput_api_helper::initialize()
if (!XInputGetState || !XInputGetCapabilities)
{
- osd_printf_verbose("Could not find XInput. Please try to reinstall DirectX runtime package.\n");
+ osd_printf_error("XInput: Could not find API functions.\n");
return -1;
}