From 8b224a58c891343283bd83566b1fbd6171617062 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 18 Jan 2023 23:46:29 +1100 Subject: [PATCH] osd: Still more XInput rhythm game controller support for Windows: * Added support for DJ Hero turntable controller. * Added support for Rock Band keyboard controller pedal. * Fixed pickup selector switch on guitar controllers. --- src/emu/inputdev.cpp | 14 +- src/osd/modules/input/input_winhybrid.cpp | 8 +- src/osd/modules/input/input_xinput.cpp | 363 ++++++++++++++++++---- src/osd/modules/input/input_xinput.h | 10 +- 4 files changed, 326 insertions(+), 69 deletions(-) diff --git a/src/emu/inputdev.cpp b/src/emu/inputdev.cpp index 2ce5720cf9b..40bdd88b8d8 100644 --- a/src/emu/inputdev.cpp +++ b/src/emu/inputdev.cpp @@ -538,17 +538,21 @@ input_device &input_class::add_device(std::unique_ptr &&new_device input_item_class input_class::standard_item_class(input_item_id itemid) const { - // most everything standard is a switch, apart from the axes if (itemid == ITEM_ID_OTHER_SWITCH || itemid < ITEM_ID_XAXIS || (itemid > ITEM_ID_SLIDER2 && itemid < ITEM_ID_ADD_ABSOLUTE1)) + { + // most everything standard is a switch, apart from the axes return ITEM_CLASS_SWITCH; - - // standard mouse axes are relative + } else if (m_devclass == DEVICE_CLASS_MOUSE || itemid == ITEM_ID_OTHER_AXIS_RELATIVE || (itemid >= ITEM_ID_ADD_RELATIVE1 && itemid <= ITEM_ID_ADD_RELATIVE16)) + { + // standard mouse axes are relative return ITEM_CLASS_RELATIVE; - - // all other standard axes are absolute + } else + { + // all other standard axes are absolute return ITEM_CLASS_ABSOLUTE; + } } diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp index 5280d42c818..4712b455d97 100644 --- a/src/osd/modules/input/input_winhybrid.cpp +++ b/src/osd/modules/input/input_winhybrid.cpp @@ -22,6 +22,8 @@ #include +namespace osd { + namespace { using namespace Microsoft::WRL; @@ -420,12 +422,14 @@ private: } // anonymous namespace +} // namespace osd + #else // defined(OSD_WINDOWS) #include "input_module.h" -MODULE_NOT_SUPPORTED(winhybrid_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "winhybrid") +namespace osd { MODULE_NOT_SUPPORTED(winhybrid_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "winhybrid") } #endif // defined(OSD_WINDOWS) -MODULE_DEFINITION(JOYSTICKINPUT_WINHYBRID, winhybrid_joystick_module) +MODULE_DEFINITION(JOYSTICKINPUT_WINHYBRID, osd::winhybrid_joystick_module) diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp index 6fb2df14873..2b40ab0eea9 100644 --- a/src/osd/modules/input/input_xinput.cpp +++ b/src/osd/modules/input/input_xinput.cpp @@ -197,6 +197,8 @@ LSX 15 C #define XINPUT_AXIS_MINVALUE (-32'767) #define XINPUT_AXIS_MAXVALUE (32'767) +namespace osd { + namespace { char const *const AXIS_NAMES_GAMEPAD[]{ @@ -332,7 +334,7 @@ protected: std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper); @@ -357,12 +359,13 @@ protected: SHORT thumb_right_y() const { return m_xinput_state.Gamepad.sThumbRY; } bool read_state(); + bool is_reset() const { return m_reset; } void set_reset() { m_reset = true; } private: bool probe_extended_type(); - uint32_t const m_player_index; + u32 const m_player_index; XINPUT_CAPABILITIES m_capabilities; XINPUT_STATE m_xinput_state; bool m_reset; @@ -376,7 +379,7 @@ xinput_device_base::xinput_device_base( std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper) : device_info(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module), @@ -386,8 +389,6 @@ xinput_device_base::xinput_device_base( m_reset(true), m_xinput_helper(helper) { - // TODO: some controller types may have different capabilities format (e.g. DJ Hero turntable) - // get friendly names for controller type and subtype char const *type_name = "unsupported"; char const *subtype_name = "unsupported"; @@ -469,22 +470,22 @@ xinput_device_base::xinput_device_base( 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", m_capabilities.Gamepad.bLeftTrigger, - count_leading_ones_32(uint32_t(m_capabilities.Gamepad.bLeftTrigger) << 24), + count_leading_ones_32(u32(m_capabilities.Gamepad.bLeftTrigger) << 24), ltcap_bad ? ", invalid" : "", m_capabilities.Gamepad.bRightTrigger, - count_leading_ones_32(uint32_t(m_capabilities.Gamepad.bRightTrigger) << 24), + count_leading_ones_32(u32(m_capabilities.Gamepad.bRightTrigger) << 24), rtcap_bad ? ", invalid" : "", m_capabilities.Gamepad.sThumbLX, - count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbLX)) << 16), + count_leading_ones_32(u32(u16(m_capabilities.Gamepad.sThumbLX)) << 16), lsxcap_bad ? ", invalid" : "", m_capabilities.Gamepad.sThumbLY, - count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbLY)) << 16), + count_leading_ones_32(u32(u16(m_capabilities.Gamepad.sThumbLY)) << 16), lsycap_bad ? ", invalid" : "", m_capabilities.Gamepad.sThumbRX, - count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbRX)) << 16), + count_leading_ones_32(u32(u16(m_capabilities.Gamepad.sThumbRX)) << 16), rsxcap_bad ? ", invalid" : "", m_capabilities.Gamepad.sThumbRY, - count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbRY)) << 16), + count_leading_ones_32(u32(u16(m_capabilities.Gamepad.sThumbRY)) << 16), rsycap_bad ? ", invalid" : ""); // ignore capabilities if invalid @@ -596,7 +597,7 @@ public: std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper); @@ -670,8 +671,8 @@ private: AXIS_TOTAL }; - uint8_t m_switches[SWITCH_TOTAL]; - int32_t m_axes[AXIS_TOTAL]; + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; }; @@ -680,7 +681,7 @@ xinput_joystick_device::xinput_joystick_device( std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper) : xinput_device_base(machine, std::move(name), std::move(id), module, player, caps, helper) @@ -691,7 +692,6 @@ xinput_joystick_device::xinput_joystick_device( void xinput_joystick_device::poll() - { // poll the device first, and skip if nothing changed if (!read_state()) @@ -792,7 +792,7 @@ void xinput_joystick_device::configure() device()->add_item( axis_names[i], axis_ids[i], - generic_axis_get_state, + generic_axis_get_state, &m_axes[AXIS_LSX + i]); } } @@ -814,7 +814,7 @@ void xinput_joystick_device::configure() device()->add_item( hat_names[i], input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_DPAD_UP + i]); } } @@ -840,7 +840,7 @@ void xinput_joystick_device::configure() device()->add_item( button_names[i], button_id++, - generic_button_get_state, + generic_button_get_state, &m_switches[offset]); } } @@ -851,7 +851,7 @@ void xinput_joystick_device::configure() device()->add_item( "Start", ITEM_ID_START, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_START]); } if (has_button(XINPUT_GAMEPAD_BACK)) @@ -859,7 +859,7 @@ void xinput_joystick_device::configure() device()->add_item( "Back", ITEM_ID_SELECT, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_BACK]); } @@ -873,7 +873,7 @@ void xinput_joystick_device::configure() device()->add_item( axis_names[4 + i], axis_ids[4 + i], - generic_axis_get_state, + generic_axis_get_state, &m_axes[AXIS_LT + i]); } } @@ -894,7 +894,7 @@ public: std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper); @@ -959,8 +959,8 @@ private: AXIS_TOTAL }; - uint8_t m_switches[SWITCH_TOTAL]; - int32_t m_axes[AXIS_TOTAL]; + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; }; @@ -969,7 +969,7 @@ xinput_guitar_device::xinput_guitar_device( std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper) : xinput_device_base(machine, std::move(name), std::move(id), module, player, caps, helper) @@ -992,7 +992,7 @@ void xinput_guitar_device::poll() // translate miscellaneous axes m_axes[AXIS_SLIDER] = normalize_absolute_axis(thumb_left_x(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); m_axes[AXIS_LSY] = normalize_absolute_axis(-thumb_left_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); - m_axes[AXIS_WHAMMY] = -normalize_absolute_axis(int32_t(thumb_right_x()) + 32'768, -65'535, 65'535); + m_axes[AXIS_WHAMMY] = -normalize_absolute_axis(s32(thumb_right_x()) + 32'768, -65'535, 65'535); // translate orientation sensors m_axes[AXIS_ORIENT_NECK] = normalize_absolute_axis(-thumb_right_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); @@ -1000,7 +1000,7 @@ void xinput_guitar_device::poll() m_axes[AXIS_ORIENT_BODY] = normalize_absolute_axis(trigger_right(), 0, 255); // translate pickup selector - m_axes[AXIS_PICKUP] = -normalize_absolute_axis(255 - trigger_right(), -255, 255); + m_axes[AXIS_PICKUP] = -normalize_absolute_axis(trigger_left(), -255, 255); } @@ -1033,7 +1033,7 @@ void xinput_guitar_device::configure() device()->add_item( name, item, - generic_axis_get_state, + generic_axis_get_state, &m_axes[AXIS_SLIDER + i]); } } @@ -1046,7 +1046,7 @@ void xinput_guitar_device::configure() device()->add_item( HAT_NAMES_GUITAR[i], input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_DPAD_UP + i]); } } @@ -1060,7 +1060,7 @@ void xinput_guitar_device::configure() device()->add_item( BUTTON_NAMES_GUITAR[i], button_id++, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_FRET1 + i]); } } @@ -1071,7 +1071,7 @@ void xinput_guitar_device::configure() device()->add_item( "Start", ITEM_ID_START, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_START]); } if (has_button(XINPUT_GAMEPAD_BACK)) @@ -1079,7 +1079,7 @@ void xinput_guitar_device::configure() device()->add_item( "Back", ITEM_ID_SELECT, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_BACK]); } } @@ -1098,7 +1098,7 @@ public: std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper); @@ -1160,8 +1160,8 @@ private: AXIS_TOTAL }; - uint8_t m_switches[SWITCH_TOTAL]; - int32_t m_axes[AXIS_TOTAL]; + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; }; @@ -1170,7 +1170,7 @@ xinput_drumkit_device::xinput_drumkit_device( std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper) : xinput_device_base(machine, std::move(name), std::move(id), module, player, caps, helper) @@ -1226,7 +1226,7 @@ void xinput_drumkit_device::configure() device()->add_item( name, item, - generic_axis_get_state, + generic_axis_get_state, &m_axes[AXIS_GREEN + i]); } } @@ -1239,7 +1239,7 @@ void xinput_drumkit_device::configure() device()->add_item( HAT_NAMES_GAMEPAD[i], input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_DPAD_UP + i]); } } @@ -1253,7 +1253,7 @@ void xinput_drumkit_device::configure() device()->add_item( BUTTON_NAMES_DRUMKIT[i], button_id++, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_GREEN + i]); } } @@ -1264,7 +1264,7 @@ void xinput_drumkit_device::configure() device()->add_item( "Start", ITEM_ID_START, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_START]); } if (has_button(XINPUT_GAMEPAD_BACK)) @@ -1272,7 +1272,233 @@ void xinput_drumkit_device::configure() device()->add_item( "Back", ITEM_ID_SELECT, - generic_button_get_state, + generic_button_get_state, + &m_switches[SWITCH_BACK]); + } +} + + + +//============================================================ +// XInput turntable handler +//============================================================ + +class xinput_turntable_device : public xinput_device_base +{ +public: + xinput_turntable_device( + running_machine &machine, + std::string &&name, + std::string &&id, + input_module &module, + u32 player, + XINPUT_CAPABILITIES const &caps, + std::shared_ptr const &helper); + + virtual void poll() override; + virtual void reset() override; + + virtual void configure() override; + +private: + static inline constexpr USHORT SWITCH_BITS[] = + { + XINPUT_GAMEPAD_A, + XINPUT_GAMEPAD_B, + XINPUT_GAMEPAD_X, + XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_LEFT_SHOULDER, + XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_LEFT_THUMB, + XINPUT_GAMEPAD_RIGHT_THUMB, + XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, + + XINPUT_GAMEPAD_DPAD_UP, + XINPUT_GAMEPAD_DPAD_DOWN, + XINPUT_GAMEPAD_DPAD_LEFT, + XINPUT_GAMEPAD_DPAD_RIGHT + }; + + enum + { + SWITCH_A, // button bits + SWITCH_B, + SWITCH_X, + SWITCH_Y, + SWITCH_LB, + SWITCH_RB, + SWITCH_LSB, + SWITCH_RSB, + SWITCH_START, + SWITCH_BACK, + + SWITCH_DPAD_UP, // D-pad bits + SWITCH_DPAD_DOWN, + SWITCH_DPAD_LEFT, + SWITCH_DPAD_RIGHT, + + SWITCH_GREEN, // RT bits + SWITCH_RED, + SWITCH_BLUE, + + SWITCH_TOTAL + }; + + enum + { + AXIS_TURNTABLE, // LSY + AXIS_EFFECT, // RSX + AXIS_CROSSFADE, // RSY + + AXIS_TOTAL + }; + + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; + u16 m_prev_effect; +}; + + +xinput_turntable_device::xinput_turntable_device( + running_machine &machine, + std::string &&name, + std::string &&id, + input_module &module, + u32 player, + XINPUT_CAPABILITIES const &caps, + std::shared_ptr const &helper) : + xinput_device_base(machine, std::move(name), std::move(id), module, player, caps, helper), + m_prev_effect(0) +{ + std::fill(std::begin(m_switches), std::end(m_switches), 0); + std::fill(std::begin(m_axes), std::end(m_axes), 0); +} + + +void xinput_turntable_device::poll() +{ + // poll the device first + bool const was_reset = is_reset(); + if (read_state()) + { + // translate button bits + for (unsigned i = 0; std::size(SWITCH_BITS) > i; ++i) + m_switches[SWITCH_A + i] = (buttons() & SWITCH_BITS[i]) ? 0xff : 0x00; + + // translate RT bits + for (unsigned i = 0; (SWITCH_BLUE - SWITCH_GREEN) >= i; ++i) + m_switches[SWITCH_GREEN + i] = BIT(trigger_right(), i) ? 0xff : 0x00; + + // translate axes + m_axes[AXIS_TURNTABLE] = thumb_left_y() * INPUT_RELATIVE_PER_PIXEL; + m_axes[AXIS_CROSSFADE] = normalize_absolute_axis(thumb_right_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); + + // convert effect dial value to relative displacement + s32 effect_delta = s32(u32(u16(thumb_right_x()))) - s32(u32(m_prev_effect)); + if (!was_reset) + { + if (0x8000 < effect_delta) + effect_delta -= 0x1'0000; + else if (-0x8000 > effect_delta) + effect_delta += 0x1'0000; + m_axes[AXIS_EFFECT] = effect_delta * INPUT_RELATIVE_PER_PIXEL; + } + m_prev_effect = u16(thumb_right_x()); + } + else + { + // we know nothing changed so we can skip most of the logic + m_prev_effect = u16(thumb_right_x()); + m_axes[AXIS_EFFECT] = 0; + } +} + + +void xinput_turntable_device::reset() +{ + set_reset(); + std::fill(std::begin(m_switches), std::end(m_switches), 0); + std::fill(std::begin(m_axes), std::end(m_axes), 0); +} + + +void xinput_turntable_device::configure() +{ + // add axes + device()->add_item( + "Turntable", + ITEM_ID_ADD_RELATIVE1, + generic_axis_get_state, + &m_axes[AXIS_TURNTABLE]); + device()->add_item( + "Effect", + ITEM_ID_ADD_RELATIVE2, + generic_axis_get_state, + &m_axes[AXIS_EFFECT]); + device()->add_item( + "Crossfade", + ITEM_ID_XAXIS, + generic_axis_get_state, + &m_axes[AXIS_CROSSFADE]); + + // add hats + for (unsigned i = 0; (SWITCH_DPAD_RIGHT - SWITCH_DPAD_UP) >= i; ++i) + { + if (has_button(SWITCH_BITS[SWITCH_DPAD_UP + i])) + { + device()->add_item( + HAT_NAMES_GAMEPAD[i], + input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order + generic_button_get_state, + &m_switches[SWITCH_DPAD_UP + i]); + } + } + + // add buttons + input_item_id button_id = ITEM_ID_BUTTON1; + for (unsigned i = 0; (SWITCH_RSB - SWITCH_A) >= i; ++i) + { + if (has_button(SWITCH_BITS[i])) + { + device()->add_item( + BUTTON_NAMES_KEYBOARD[i], + button_id++, + generic_button_get_state, + &m_switches[SWITCH_A + i]); + } + } + device()->add_item( + "Green", + button_id++, + generic_button_get_state, + &m_switches[SWITCH_GREEN]); + device()->add_item( + "Red", + button_id++, + generic_button_get_state, + &m_switches[SWITCH_RED]); + device()->add_item( + "Blue", + button_id++, + generic_button_get_state, + &m_switches[SWITCH_BLUE]); + + // add start/back + if (has_button(XINPUT_GAMEPAD_START)) + { + device()->add_item( + "Start", + ITEM_ID_START, + generic_button_get_state, + &m_switches[SWITCH_START]); + } + if (has_button(XINPUT_GAMEPAD_BACK)) + { + device()->add_item( + "Back", + ITEM_ID_SELECT, + generic_button_get_state, &m_switches[SWITCH_BACK]); } } @@ -1291,7 +1517,7 @@ public: std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper); @@ -1346,13 +1572,14 @@ private: enum { - AXIS_VELOCITY, + AXIS_VELOCITY, // field in LSX + AXIS_PEDAL, // RSY, most positive value neutral AXIS_TOTAL }; - uint8_t m_switches[SWITCH_TOTAL]; - int32_t m_axes[AXIS_TOTAL]; + u8 m_switches[SWITCH_TOTAL]; + s32 m_axes[AXIS_TOTAL]; }; @@ -1361,7 +1588,7 @@ xinput_keyboard_device::xinput_keyboard_device( std::string &&name, std::string &&id, input_module &module, - uint32_t player, + u32 player, XINPUT_CAPABILITIES const &caps, std::shared_ptr const &helper) : xinput_device_base(machine, std::move(name), std::move(id), module, player, caps, helper) @@ -1375,7 +1602,6 @@ void xinput_keyboard_device::poll() { // TODO: how many bits are really velocity? // TODO: how are touch strip and overdrive read? - // TODO: how are pedals read (maybe expression on RSY)? // poll the device first, and skip if nothing changed if (!read_state()) @@ -1394,8 +1620,9 @@ void xinput_keyboard_device::poll() } m_switches[SWITCH_C3] = BIT(thumb_left_x(), 15) ? 0xff : 0x00; - // translate velocity + // translate axes m_axes[AXIS_VELOCITY] = -normalize_absolute_axis(BIT(thumb_left_x(), 8, 7), -127, 127); + m_axes[AXIS_PEDAL] = -normalize_absolute_axis(32'767 - thumb_right_y(), -32'767, 32'767); } @@ -1409,12 +1636,17 @@ void xinput_keyboard_device::reset() void xinput_keyboard_device::configure() { - // add velocity axis + // add axes device()->add_item( "Velocity", ITEM_ID_SLIDER1, - generic_axis_get_state, + generic_axis_get_state, &m_axes[AXIS_VELOCITY]); + device()->add_item( + "Pedal", + ITEM_ID_SLIDER2, + generic_axis_get_state, + &m_axes[AXIS_PEDAL]); // add hats for (unsigned i = 0; (SWITCH_DPAD_RIGHT - SWITCH_DPAD_UP) >= i; ++i) @@ -1424,7 +1656,7 @@ void xinput_keyboard_device::configure() device()->add_item( HAT_NAMES_GAMEPAD[i], input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_DPAD_UP + i]); } } @@ -1438,7 +1670,7 @@ void xinput_keyboard_device::configure() device()->add_item( BUTTON_NAMES_KEYBOARD[i], button_id++, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_A + i]); } } @@ -1451,7 +1683,7 @@ void xinput_keyboard_device::configure() device()->add_item( util::string_format(key_formats[i % 12], (i / 12) + 1), (ITEM_ID_BUTTON32 >= button_id) ? button_id++ : ITEM_ID_OTHER_SWITCH, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_C1 + i]); } @@ -1461,7 +1693,7 @@ void xinput_keyboard_device::configure() device()->add_item( "Start", ITEM_ID_START, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_START]); } if (has_button(XINPUT_GAMEPAD_BACK)) @@ -1469,7 +1701,7 @@ void xinput_keyboard_device::configure() device()->add_item( "Back", ITEM_ID_SELECT, - generic_button_get_state, + generic_button_get_state, &m_switches[SWITCH_BACK]); } } @@ -1527,9 +1759,10 @@ private: } // anonymous namespace + int xinput_api_helper::initialize() { - m_xinput_dll = osd::dynamic_module::open(XINPUT_LIBRARIES); + m_xinput_dll = dynamic_module::open(XINPUT_LIBRARIES); XInputGetState = m_xinput_dll->bind("XInputGetState"); XInputGetCapabilities = m_xinput_dll->bind("XInputGetCapabilities"); @@ -1597,6 +1830,16 @@ device_info *xinput_api_helper::create_xinput_device(running_machine &machine, U caps, shared_from_this()); break; + case 0x17: + devinfo = &module.devicelist().create_device( + machine, + device_name, + device_name, + module, + index, + caps, + shared_from_this()); + break; default: devinfo = &module.devicelist().create_device( machine, @@ -1625,12 +1868,14 @@ device_info *xinput_api_helper::create_xinput_device(running_machine &machine, U return devinfo; } +} // namespace osd + #else // defined(OSD_WINDOWS) #include "input_module.h" -MODULE_NOT_SUPPORTED(xinput_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "xinput") +namespace osd { MODULE_NOT_SUPPORTED(xinput_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "xinput") } #endif // defined(OSD_WINDOWS) -MODULE_DEFINITION(JOYSTICKINPUT_XINPUT, xinput_joystick_module) +MODULE_DEFINITION(JOYSTICKINPUT_XINPUT, osd::xinput_joystick_module) diff --git a/src/osd/modules/input/input_xinput.h b/src/osd/modules/input/input_xinput.h index edf3dc23ce5..363df481668 100644 --- a/src/osd/modules/input/input_xinput.h +++ b/src/osd/modules/input/input_xinput.h @@ -12,6 +12,8 @@ #include +namespace osd { + class xinput_api_helper : public std::enable_shared_from_this { public: @@ -35,9 +37,11 @@ private: typedef DWORD (WINAPI *xinput_get_state_fn)(DWORD, XINPUT_STATE *); typedef DWORD (WINAPI *xinput_get_caps_fn)(DWORD, DWORD, XINPUT_CAPABILITIES *); - osd::dynamic_module::ptr m_xinput_dll = nullptr; - xinput_get_state_fn XInputGetState = nullptr; - xinput_get_caps_fn XInputGetCapabilities = nullptr; + dynamic_module::ptr m_xinput_dll = nullptr; + xinput_get_state_fn XInputGetState = nullptr; + xinput_get_caps_fn XInputGetCapabilities = nullptr; }; +} // namespace osd + #endif // MAME_OSD_INPUT_INPUT_XINPUT_H