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.
This commit is contained in:
Vas Crabb 2023-01-18 23:46:29 +11:00
parent 5908f5a4ab
commit 8b224a58c8
4 changed files with 326 additions and 69 deletions

View File

@ -538,17 +538,21 @@ input_device &input_class::add_device(std::unique_ptr<input_device> &&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;
}
}

View File

@ -22,6 +22,8 @@
#include <wbemcli.h>
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)

View File

@ -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<xinput_api_helper> 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<xinput_api_helper> 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<xinput_api_helper> 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<xinput_api_helper> 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<int32_t>,
generic_axis_get_state<s32>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&m_switches[offset]);
}
}
@ -851,7 +851,7 @@ void xinput_joystick_device::configure()
device()->add_item(
"Start",
ITEM_ID_START,
generic_button_get_state<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<int32_t>,
generic_axis_get_state<s32>,
&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<xinput_api_helper> 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<xinput_api_helper> 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<uint32_t>,
generic_axis_get_state<s32>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<xinput_api_helper> 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<xinput_api_helper> 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<uint32_t>,
generic_axis_get_state<s32>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<xinput_api_helper> 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<xinput_api_helper> 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<s32>,
&m_axes[AXIS_TURNTABLE]);
device()->add_item(
"Effect",
ITEM_ID_ADD_RELATIVE2,
generic_axis_get_state<s32>,
&m_axes[AXIS_EFFECT]);
device()->add_item(
"Crossfade",
ITEM_ID_XAXIS,
generic_axis_get_state<s32>,
&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<u8>,
&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<u8>,
&m_switches[SWITCH_A + i]);
}
}
device()->add_item(
"Green",
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_GREEN]);
device()->add_item(
"Red",
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_RED]);
device()->add_item(
"Blue",
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_BLUE]);
// add start/back
if (has_button(XINPUT_GAMEPAD_START))
{
device()->add_item(
"Start",
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
}
if (has_button(XINPUT_GAMEPAD_BACK))
{
device()->add_item(
"Back",
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&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<xinput_api_helper> 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<xinput_api_helper> 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<int32_t>,
generic_axis_get_state<s32>,
&m_axes[AXIS_VELOCITY]);
device()->add_item(
"Pedal",
ITEM_ID_SLIDER2,
generic_axis_get_state<s32>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<uint8_t>,
generic_button_get_state<u8>,
&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<xinput_get_state_fn>("XInputGetState");
XInputGetCapabilities = m_xinput_dll->bind<xinput_get_caps_fn>("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<xinput_turntable_device>(
machine,
device_name,
device_name,
module,
index,
caps,
shared_from_this());
break;
default:
devinfo = &module.devicelist().create_device<xinput_joystick_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)

View File

@ -12,6 +12,8 @@
#include <memory>
namespace osd {
class xinput_api_helper : public std::enable_shared_from_this<xinput_api_helper>
{
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