summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_sdl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/input/input_sdl.cpp')
-rw-r--r--src/osd/modules/input/input_sdl.cpp567
1 files changed, 408 insertions, 159 deletions
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 1eaed99f16b..f1fb0241b40 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -33,6 +33,7 @@
#include <algorithm>
#include <cctype>
#include <chrono>
+#include <cmath>
#include <cstddef>
#include <cstring>
#include <initializer_list>
@@ -63,7 +64,7 @@ char const *const CONTROLLER_AXIS_XBOX[]{
"LT",
"RT" };
-[[maybe_unused]] char const *const CONTROLLER_AXIS_PS[]{
+char const *const CONTROLLER_AXIS_PS[]{
"LSX",
"LSY",
"RSX",
@@ -71,7 +72,7 @@ char const *const CONTROLLER_AXIS_XBOX[]{
"L2",
"R2" };
-[[maybe_unused]] char const *const CONTROLLER_AXIS_SWITCH[]{
+char const *const CONTROLLER_AXIS_SWITCH[]{
"LSX",
"LSY",
"RSX",
@@ -102,7 +103,7 @@ char const *const CONTROLLER_BUTTON_XBOX360[]{
"P4",
"Touchpad" };
-[[maybe_unused]] char const *const CONTROLLER_BUTTON_XBOXONE[]{
+char const *const CONTROLLER_BUTTON_XBOXONE[]{
"A",
"B",
"X",
@@ -125,7 +126,7 @@ char const *const CONTROLLER_BUTTON_XBOX360[]{
"P4",
"Touchpad" };
-[[maybe_unused]] char const *const CONTROLLER_BUTTON_PS3[]{
+char const *const CONTROLLER_BUTTON_PS3[]{
"Cross",
"Circle",
"Square",
@@ -148,7 +149,7 @@ char const *const CONTROLLER_BUTTON_XBOX360[]{
"P4",
"Touchpad" };
-[[maybe_unused]] char const *const CONTROLLER_BUTTON_PS4[]{
+char const *const CONTROLLER_BUTTON_PS4[]{
"Cross",
"Circle",
"Square",
@@ -171,7 +172,7 @@ char const *const CONTROLLER_BUTTON_XBOX360[]{
"P4",
"Touchpad" };
-[[maybe_unused]] char const *const CONTROLLER_BUTTON_PS5[]{
+char const *const CONTROLLER_BUTTON_PS5[]{
"Cross",
"Circle",
"Square",
@@ -194,7 +195,7 @@ char const *const CONTROLLER_BUTTON_XBOX360[]{
"P4",
"Touchpad" };
-[[maybe_unused]] char const *const CONTROLLER_BUTTON_SWITCH[]{
+char const *const CONTROLLER_BUTTON_SWITCH[]{
"A",
"B",
"X",
@@ -607,6 +608,7 @@ public:
virtual void reset() override
{
+ sdl_device::reset();
memset(&m_keyboard.state, 0, sizeof(m_keyboard.state));
m_capslock_pressed = std::chrono::steady_clock::time_point::min();
}
@@ -617,13 +619,8 @@ public:
for (int keynum = 0; m_trans_table[keynum].mame_key != ITEM_ID_INVALID; keynum++)
{
input_item_id itemid = m_trans_table[keynum].mame_key;
-
- // generate the default / modified name
- char defname[20];
- snprintf(defname, sizeof(defname) - 1, "%s", m_trans_table[keynum].ui_name);
-
device.add_item(
- defname,
+ m_trans_table[keynum].ui_name,
std::string_view(),
itemid,
generic_button_get_state<s32>,
@@ -647,29 +644,18 @@ private:
//============================================================
-// sdl_mouse_device
+// sdl_mouse_device_base
//============================================================
-class sdl_mouse_device : public sdl_device
+class sdl_mouse_device_base : public sdl_device
{
public:
- sdl_mouse_device(std::string &&name, std::string &&id, input_module &module) :
- sdl_device(std::move(name), std::move(id), module),
- m_mouse({0}),
- m_x(0),
- m_y(0),
- m_v(0),
- m_h(0)
- {
- }
-
virtual void poll(bool relative_reset) override
{
sdl_device::poll(relative_reset);
+
if (relative_reset)
{
- m_mouse.lX = std::exchange(m_x, 0);
- m_mouse.lY = std::exchange(m_y, 0);
m_mouse.lV = std::exchange(m_v, 0);
m_mouse.lH = std::exchange(m_h, 0);
}
@@ -677,13 +663,30 @@ public:
virtual void reset() override
{
+ sdl_device::reset();
memset(&m_mouse, 0, sizeof(m_mouse));
- m_x = m_y = m_v = m_h = 0;
+ m_v = m_h = 0;
}
- virtual void configure(input_device &device) override
+protected:
+ // state information for a mouse
+ struct mouse_state
{
- // add the axes
+ s32 lX, lY, lV, lH;
+ s32 buttons[MAX_BUTTONS];
+ };
+
+ sdl_mouse_device_base(std::string &&name, std::string &&id, input_module &module) :
+ sdl_device(std::move(name), std::move(id), module),
+ m_mouse({0}),
+ m_v(0),
+ m_h(0)
+ {
+ }
+
+ void add_common_items(input_device &device, unsigned buttons)
+ {
+ // add horizontal and vertical axes - relative for a mouse or absolute for a gun
device.add_item(
"X",
std::string_view(),
@@ -696,6 +699,62 @@ public:
ITEM_ID_YAXIS,
generic_axis_get_state<s32>,
&m_mouse.lY);
+
+ // add buttons
+ for (int button = 0; button < buttons; button++)
+ {
+ input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
+ int const offset = button ^ (((1 == button) || (2 == button)) ? 3 : 0);
+ device.add_item(
+ default_button_name(button),
+ std::string_view(),
+ itemid,
+ generic_button_get_state<s32>,
+ &m_mouse.buttons[offset]);
+ }
+ }
+
+ mouse_state m_mouse;
+ s32 m_v, m_h;
+};
+
+
+//============================================================
+// sdl_mouse_device
+//============================================================
+
+class sdl_mouse_device : public sdl_mouse_device_base
+{
+public:
+ sdl_mouse_device(std::string &&name, std::string &&id, input_module &module) :
+ sdl_mouse_device_base(std::move(name), std::move(id), module),
+ m_x(0),
+ m_y(0)
+ {
+ }
+
+ virtual void poll(bool relative_reset) override
+ {
+ sdl_mouse_device_base::poll(relative_reset);
+
+ if (relative_reset)
+ {
+ m_mouse.lX = std::exchange(m_x, 0);
+ m_mouse.lY = std::exchange(m_y, 0);
+ }
+ }
+
+ virtual void reset() override
+ {
+ sdl_mouse_device_base::reset();
+ m_x = m_y = 0;
+ }
+
+ virtual void configure(input_device &device) override
+ {
+ add_common_items(device, 5);
+
+ // add scroll axes
device.add_item(
"Scroll V",
std::string_view(),
@@ -708,60 +767,206 @@ public:
ITEM_ID_RZAXIS,
generic_axis_get_state<s32>,
&m_mouse.lH);
+ }
+
+ virtual void process_event(SDL_Event const &event) override
+ {
+ switch (event.type)
+ {
+ case SDL_MOUSEMOTION:
+ m_x += event.motion.xrel * input_device::RELATIVE_PER_PIXEL;
+ m_y += event.motion.yrel * input_device::RELATIVE_PER_PIXEL;
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ m_mouse.buttons[event.button.button - 1] = 0x80;
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ m_mouse.buttons[event.button.button - 1] = 0;
+ break;
+
+ case SDL_MOUSEWHEEL:
+ // adjust SDL 1-per-click to match Win32 120-per-click
+#if SDL_VERSION_ATLEAST(2, 0, 18)
+ m_v += std::lround(event.wheel.preciseY * 120 * input_device::RELATIVE_PER_PIXEL);
+ m_h += std::lround(event.wheel.preciseX * 120 * input_device::RELATIVE_PER_PIXEL);
+#else
+ m_v += event.wheel.y * 120 * input_device::RELATIVE_PER_PIXEL;
+ m_h += event.wheel.x * 120 * input_device::RELATIVE_PER_PIXEL;
+#endif
+ break;
+ }
+ }
+
+private:
+ s32 m_x, m_y;
+};
+
+
+//============================================================
+// sdl_lightgun_device
+//============================================================
+
+class sdl_lightgun_device : public sdl_mouse_device_base
+{
+public:
+ sdl_lightgun_device(std::string &&name, std::string &&id, input_module &module) :
+ sdl_mouse_device_base(std::move(name), std::move(id), module),
+ m_x(0),
+ m_y(0),
+ m_window(0)
+ {
+ }
+
+ virtual void poll(bool relative_reset) override
+ {
+ sdl_mouse_device_base::poll(relative_reset);
- // add the buttons
- for (int button = 0; button < 4; button++)
+ SDL_Window *const win(m_window ? SDL_GetWindowFromID(m_window) : nullptr);
+ if (win)
{
- input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
- int const offset = button ^ (((1 == button) || (2 == button)) ? 3 : 0);
- device.add_item(
- default_button_name(button),
- std::string_view(),
- itemid,
- generic_button_get_state<s32>,
- &m_mouse.buttons[offset]);
+ int w, h;
+ SDL_GetWindowSize(win, &w, &h);
+ m_mouse.lX = normalize_absolute_axis(m_x, 0, w - 1);
+ m_mouse.lY = normalize_absolute_axis(m_y, 0, h - 1);
+ }
+ else
+ {
+ m_mouse.lX = 0;
+ m_mouse.lY = 0;
}
}
+ virtual void reset() override
+ {
+ sdl_mouse_device_base::reset();
+ m_x = m_y = 0;
+ m_window = 0;
+ }
+
+ virtual void configure(input_device &device) override
+ {
+ add_common_items(device, 5);
+
+ // add scroll axes
+ device.add_item(
+ "Scroll V",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE1,
+ generic_axis_get_state<s32>,
+ &m_mouse.lV);
+ device.add_item(
+ "Scroll H",
+ std::string_view(),
+ ITEM_ID_ADD_RELATIVE2,
+ generic_axis_get_state<s32>,
+ &m_mouse.lH);
+ }
+
virtual void process_event(SDL_Event const &event) override
{
switch (event.type)
{
case SDL_MOUSEMOTION:
- m_x += event.motion.xrel * input_device::RELATIVE_PER_PIXEL;
- m_y += event.motion.yrel * input_device::RELATIVE_PER_PIXEL;
+ m_x = event.motion.x;
+ m_y = event.motion.y;
+ m_window = event.motion.windowID;
break;
case SDL_MOUSEBUTTONDOWN:
m_mouse.buttons[event.button.button - 1] = 0x80;
+ m_x = event.button.x;
+ m_y = event.button.y;
+ m_window = event.button.windowID;
break;
case SDL_MOUSEBUTTONUP:
m_mouse.buttons[event.button.button - 1] = 0;
+ m_x = event.button.x;
+ m_y = event.button.y;
+ m_window = event.button.windowID;
break;
case SDL_MOUSEWHEEL:
+ // adjust SDL 1-per-click to match Win32 120-per-click
#if SDL_VERSION_ATLEAST(2, 0, 18)
- m_v += event.wheel.preciseY * input_device::RELATIVE_PER_PIXEL;
- m_h += event.wheel.preciseX * input_device::RELATIVE_PER_PIXEL;
+ m_v += std::lround(event.wheel.preciseY * 120 * input_device::RELATIVE_PER_PIXEL);
+ m_h += std::lround(event.wheel.preciseX * 120 * input_device::RELATIVE_PER_PIXEL);
#else
- m_v += event.wheel.y * input_device::RELATIVE_PER_PIXEL;
- m_h += event.wheel.x * input_device::RELATIVE_PER_PIXEL;
+ m_v += event.wheel.y * 120 * input_device::RELATIVE_PER_PIXEL;
+ m_h += event.wheel.x * 120 * input_device::RELATIVE_PER_PIXEL;
#endif
break;
+
+ case SDL_WINDOWEVENT:
+ if ((event.window.windowID == m_window) && (SDL_WINDOWEVENT_LEAVE == event.window.event))
+ m_window = 0;
+ break;
}
}
private:
- // state information for a mouse
- struct mouse_state
+ s32 m_x, m_y;
+ u32 m_window;
+};
+
+
+//============================================================
+// sdl_dual_lightgun_device
+//============================================================
+
+class sdl_dual_lightgun_device : public sdl_mouse_device_base
+{
+public:
+ sdl_dual_lightgun_device(std::string &&name, std::string &&id, input_module &module, u8 index) :
+ sdl_mouse_device_base(std::move(name), std::move(id), module),
+ m_index(index)
{
- s32 lX, lY, lV, lH;
- s32 buttons[MAX_BUTTONS];
- };
+ }
- mouse_state m_mouse;
- s32 m_x, m_y, m_v, m_h;
+ virtual void configure(input_device &device) override
+ {
+ add_common_items(device, 2);
+ }
+
+ virtual void process_event(SDL_Event const &event) override
+ {
+ switch (event.type)
+ {
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ SDL_Window *const win(SDL_GetWindowFromID(event.button.windowID));
+ u8 const button = translate_button(event);
+ if (win && ((button / 2) == m_index))
+ {
+ int w, h;
+ SDL_GetWindowSize(win, &w, &h);
+ m_mouse.buttons[(button & 1) << 1] = 0x80;
+ m_mouse.lX = normalize_absolute_axis(event.button.x, 0, w - 1);
+ m_mouse.lY = normalize_absolute_axis(event.button.y, 0, h - 1);
+ }
+ }
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ {
+ u8 const button = translate_button(event);
+ if ((button / 2) == m_index)
+ m_mouse.buttons[(button & 1) << 1] = 0;
+ }
+ break;
+ }
+ }
+
+private:
+ static u8 translate_button(SDL_Event const &event)
+ {
+ u8 const index(event.button.button - 1);
+ return index ^ (((1 == index) || (2 == index)) ? 3 : 0);
+ }
+
+ u8 const m_index;
};
@@ -1113,25 +1318,20 @@ public:
~sdl_joystick_device()
{
- if (m_joydevice)
- {
- if (m_hapdevice)
- {
- SDL_HapticClose(m_hapdevice);
- m_hapdevice = nullptr;
- }
- SDL_JoystickClose(m_joydevice);
- m_joydevice = nullptr;
- }
+ close_device();
}
virtual void reset() override
{
- memset(&m_joystick, 0, sizeof(m_joystick));
+ sdl_joystick_device_base::reset();
+ clear_buffer();
}
virtual void process_event(SDL_Event const &event) override
{
+ if (!m_joydevice)
+ return;
+
switch (event.type)
{
case SDL_JOYAXISMOTION:
@@ -1167,17 +1367,8 @@ public:
case SDL_JOYDEVICEREMOVED:
osd_printf_verbose("Joystick: %s [ID %s] disconnected\n", name(), id());
clear_instance();
- reset();
- if (m_joydevice)
- {
- if (m_hapdevice)
- {
- SDL_HapticClose(m_hapdevice);
- m_hapdevice = nullptr;
- }
- SDL_JoystickClose(m_joydevice);
- m_joydevice = nullptr;
- }
+ clear_buffer();
+ close_device();
break;
}
}
@@ -1214,6 +1405,25 @@ protected:
private:
SDL_Joystick *m_joydevice;
SDL_Haptic *m_hapdevice;
+
+ void clear_buffer()
+ {
+ memset(&m_joystick, 0, sizeof(m_joystick));
+ }
+
+ void close_device()
+ {
+ if (m_joydevice)
+ {
+ if (m_hapdevice)
+ {
+ SDL_HapticClose(m_hapdevice);
+ m_hapdevice = nullptr;
+ }
+ SDL_JoystickClose(m_joydevice);
+ m_joydevice = nullptr;
+ }
+ }
};
@@ -1280,11 +1490,7 @@ public:
~sdl_game_controller_device()
{
- if (m_ctrldevice)
- {
- SDL_GameControllerClose(m_ctrldevice);
- m_ctrldevice = nullptr;
- }
+ close_device();
}
virtual void configure(input_device &device) override
@@ -1293,10 +1499,7 @@ public:
char const *const *axisnames = CONTROLLER_AXIS_XBOX;
char const *const *buttonnames = CONTROLLER_BUTTON_XBOX360;
bool digitaltriggers = false;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
bool avoidpaddles = false;
-#endif
-#if SDL_VERSION_ATLEAST(2, 0, 12)
auto const ctrltype = SDL_GameControllerGetType(m_ctrldevice);
switch (ctrltype)
{
@@ -1329,14 +1532,12 @@ public:
buttonnames = CONTROLLER_BUTTON_SWITCH;
digitaltriggers = true;
break;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
//case SDL_CONTROLLER_TYPE_VIRTUAL:
case SDL_CONTROLLER_TYPE_PS5:
osd_printf_verbose("Game Controller: ... PlayStation 5 type\n");
axisnames = CONTROLLER_AXIS_PS;
buttonnames = CONTROLLER_BUTTON_PS5;
break;
-#endif
#if SDL_VERSION_ATLEAST(2, 0, 16)
//case SDL_CONTROLLER_TYPE_AMAZON_LUNA:
case SDL_CONTROLLER_TYPE_GOOGLE_STADIA:
@@ -1365,7 +1566,6 @@ public:
osd_printf_verbose("Game Controller: ... unrecognized type (%d)\n", int(ctrltype));
break;
}
-#endif
// keep track of item numbers as we add controls
std::pair<input_item_id, input_item_id> axisitems[SDL_CONTROLLER_AXIS_MAX];
@@ -1395,9 +1595,7 @@ public:
for (auto [axis, item, buttontest] : axes)
{
bool avail = !buttontest || !digitaltriggers;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
avail = avail && SDL_GameControllerHasAxis(m_ctrldevice, axis);
-#endif
if (avail)
{
auto const binding = SDL_GameControllerGetBindForAxis(m_ctrldevice, axis);
@@ -1437,17 +1635,13 @@ public:
{ SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, true },
{ SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_AXIS_INVALID, true },
{ SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_AXIS_INVALID, true },
-#if SDL_VERSION_ATLEAST(2, 0, 14)
{ SDL_CONTROLLER_BUTTON_PADDLE1, SDL_CONTROLLER_AXIS_INVALID, true },
{ SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_AXIS_INVALID, true },
{ SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_AXIS_INVALID, true },
{ SDL_CONTROLLER_BUTTON_PADDLE4, SDL_CONTROLLER_AXIS_INVALID, true },
-#endif
{ SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_AXIS_INVALID, false },
-#if SDL_VERSION_ATLEAST(2, 0, 14)
{ SDL_CONTROLLER_BUTTON_MISC1, SDL_CONTROLLER_AXIS_INVALID, false },
{ SDL_CONTROLLER_BUTTON_TOUCHPAD, SDL_CONTROLLER_AXIS_INVALID, false },
-#endif
};
input_item_id button_item = ITEM_ID_BUTTON1;
unsigned buttoncount = 0;
@@ -1457,9 +1651,7 @@ public:
input_item_id actual = ITEM_ID_INVALID;
if (SDL_CONTROLLER_BUTTON_INVALID != button)
{
-#if SDL_VERSION_ATLEAST(2, 0, 14)
avail = SDL_GameControllerHasButton(m_ctrldevice, button);
-#endif
if (avail)
{
auto const binding = SDL_GameControllerGetBindForButton(m_ctrldevice, button);
@@ -1486,9 +1678,7 @@ public:
}
else
{
-#if SDL_VERSION_ATLEAST(2, 0, 14)
avail = SDL_GameControllerHasAxis(m_ctrldevice, axis);
-#endif
if (avail)
{
auto const binding = SDL_GameControllerGetBindForAxis(m_ctrldevice, axis);
@@ -1538,9 +1728,7 @@ public:
for (auto [button, item] : fixedbuttons)
{
bool avail = true;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
avail = SDL_GameControllerHasButton(m_ctrldevice, button);
-#endif
if (avail)
{
auto const binding = SDL_GameControllerGetBindForButton(m_ctrldevice, button);
@@ -1611,7 +1799,6 @@ public:
{
// took trigger buttons
}
-#if SDL_VERSION_ATLEAST(2, 0, 14)
else if (add_axis_inc_dec_assignment(assignments, IPT_AD_STICK_Z, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2]))
{
// took P1/P2
@@ -1620,7 +1807,6 @@ public:
{
// took P3/P4
}
-#endif
}
// prefer trigger axes for pedals, otherwise take half axes and buttons
@@ -1706,22 +1892,18 @@ public:
{
// took digital triggers
}
-#if SDL_VERSION_ATLEAST(2, 0, 14)
else if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2]))
{
// took upper paddles
}
-#endif
else if (consume_trigger_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first))
{
// took analog triggers
}
-#if SDL_VERSION_ATLEAST(2, 0, 14)
else if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE3], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE4]))
{
// took lower paddles
}
-#endif
else if (consume_axis_pair(assignments, IPT_UI_PREV_GROUP, IPT_UI_NEXT_GROUP, diraxis[1][1]))
{
// took secondary Y
@@ -1732,7 +1914,6 @@ public:
}
// try to get a matching pair of buttons for page up/down
-#if SDL_VERSION_ATLEAST(2, 0, 14)
if (!avoidpaddles && consume_button_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, buttonitems[SDL_CONTROLLER_BUTTON_PADDLE1], buttonitems[SDL_CONTROLLER_BUTTON_PADDLE2]))
{
// took upper paddles
@@ -1742,7 +1923,6 @@ public:
// took lower paddles
}
else
-#endif
if (consume_trigger_pair(assignments, IPT_UI_PAGE_UP, IPT_UI_PAGE_DOWN, axisitems[SDL_CONTROLLER_AXIS_TRIGGERLEFT].first, axisitems[SDL_CONTROLLER_AXIS_TRIGGERRIGHT].first))
{
// took analog triggers
@@ -1871,11 +2051,15 @@ public:
virtual void reset() override
{
- memset(&m_controller, 0, sizeof(m_controller));
+ sdl_joystick_device_base::reset();
+ clear_buffer();
}
virtual void process_event(SDL_Event const &event) override
{
+ if (!m_ctrldevice)
+ return;
+
switch (event.type)
{
case SDL_CONTROLLERAXISMOTION:
@@ -1902,12 +2086,8 @@ public:
case SDL_CONTROLLERDEVICEREMOVED:
osd_printf_verbose("Game Controller: %s [ID %s] disconnected\n", name(), id());
clear_instance();
- reset();
- if (m_ctrldevice)
- {
- SDL_GameControllerClose(m_ctrldevice);
- m_ctrldevice = nullptr;
- }
+ clear_buffer();
+ close_device();
break;
}
}
@@ -1933,6 +2113,20 @@ private:
sdl_controller_state m_controller;
SDL_GameController *m_ctrldevice;
+
+ void clear_buffer()
+ {
+ memset(&m_controller, 0, sizeof(m_controller));
+ }
+
+ void close_device()
+ {
+ if (m_ctrldevice)
+ {
+ SDL_GameControllerClose(m_ctrldevice);
+ m_ctrldevice = nullptr;
+ }
+ }
};
@@ -1977,8 +2171,7 @@ class sdl_keyboard_module : public sdl_input_module<sdl_keyboard_device>
{
public:
sdl_keyboard_module() :
- sdl_input_module<sdl_keyboard_device>(OSD_KEYBOARDINPUT_PROVIDER, "sdl"),
- m_key_trans_table(nullptr)
+ sdl_input_module<sdl_keyboard_device>(OSD_KEYBOARDINPUT_PROVIDER, "sdl")
{
}
@@ -1986,14 +2179,14 @@ public:
{
sdl_input_module<sdl_keyboard_device>::input_init(machine);
- static int const event_types[] = {
+ constexpr int event_types[] = {
int(SDL_KEYDOWN),
int(SDL_KEYUP) };
subscribe(osd(), event_types);
// Read our keymap and store a pointer to our table
- m_key_trans_table = sdlinput_read_keymap();
+ sdlinput_read_keymap();
osd_printf_verbose("Keyboard: Start initialization\n");
@@ -2009,12 +2202,27 @@ public:
}
private:
- keyboard_trans_table *sdlinput_read_keymap()
+ void sdlinput_read_keymap()
{
keyboard_trans_table &default_table = keyboard_trans_table::instance();
+ // Allocate a block of translation entries big enough to hold what's in the default table
+ auto key_trans_entries = std::make_unique<key_trans_entry []>(default_table.size());
+
+ // copy the elements from the default table and ask SDL for key names
+ for (int i = 0; i < default_table.size(); i++)
+ {
+ key_trans_entries[i] = default_table[i];
+ char const *const name = SDL_GetScancodeName(SDL_Scancode(default_table[i].sdl_scancode));
+ if (name && *name)
+ key_trans_entries[i].ui_name = name;
+ }
+
+ // Allocate the trans table to be associated with the machine so we don't have to free it
+ m_key_trans_table = std::make_unique<keyboard_trans_table>(std::move(key_trans_entries), default_table.size());
+
if (!options()->bool_value(SDLOPTION_KEYMAP))
- return &default_table;
+ return;
const char *const keymap_filename = dynamic_cast<sdl_options const &>(*options()).keymap_file();
osd_printf_verbose("Keymap: Start reading keymap_file %s\n", keymap_filename);
@@ -2023,19 +2231,9 @@ private:
if (!keymap_file)
{
osd_printf_warning("Keymap: Unable to open keymap %s, using default\n", keymap_filename);
- return &default_table;
+ return;
}
- // Allocate a block of translation entries big enough to hold what's in the default table
- auto key_trans_entries = std::make_unique<key_trans_entry[]>(default_table.size());
-
- // copy the elements from the default table
- for (int i = 0; i < default_table.size(); i++)
- key_trans_entries[i] = default_table[i];
-
- // Allocate the trans table to be associated with the machine so we don't have to free it
- m_custom_table = std::make_unique<keyboard_trans_table>(std::move(key_trans_entries), default_table.size());
-
int line = 1;
int sdl2section = 0;
while (!feof(keymap_file))
@@ -2068,7 +2266,7 @@ private:
if (sk >= 0 && index >= 0)
{
- key_trans_entry &entry = (*m_custom_table)[index];
+ key_trans_entry &entry = (*m_key_trans_table)[index];
entry.sdl_scancode = sk;
entry.ui_name = const_cast<char *>(m_ui_names.emplace_back(kns).c_str());
osd_printf_verbose("Keymap: Mapped <%s> to <%s> with ui-text <%s>\n", sks, mks, kns);
@@ -2083,12 +2281,9 @@ private:
}
fclose(keymap_file);
osd_printf_verbose("Keymap: Processed %d lines\n", line);
-
- return m_custom_table.get();
}
- keyboard_trans_table *m_key_trans_table;
- std::unique_ptr<keyboard_trans_table> m_custom_table;
+ std::unique_ptr<keyboard_trans_table> m_key_trans_table;
std::list<std::string> m_ui_names;
};
@@ -2108,7 +2303,7 @@ public:
{
sdl_input_module::input_init(machine);
- static int const event_types[] = {
+ constexpr int event_types[] = {
int(SDL_MOUSEMOTION),
int(SDL_MOUSEBUTTONDOWN),
int(SDL_MOUSEBUTTONUP),
@@ -2131,6 +2326,73 @@ public:
//============================================================
+// sdl_lightgun_module
+//============================================================
+
+class sdl_lightgun_module : public sdl_input_module<sdl_mouse_device_base>
+{
+public:
+ sdl_lightgun_module() : sdl_input_module<sdl_mouse_device_base>(OSD_LIGHTGUNINPUT_PROVIDER, "sdl")
+ {
+ }
+
+ virtual void input_init(running_machine &machine) override
+ {
+ auto &sdlopts = dynamic_cast<sdl_options const &>(*options());
+ sdl_input_module::input_init(machine);
+ bool const dual(sdlopts.dual_lightgun());
+
+ if (!dual)
+ {
+ constexpr int event_types[] = {
+ int(SDL_MOUSEMOTION),
+ int(SDL_MOUSEBUTTONDOWN),
+ int(SDL_MOUSEBUTTONUP),
+ int(SDL_MOUSEWHEEL),
+ int(SDL_WINDOWEVENT) };
+ subscribe(osd(), event_types);
+ }
+ else
+ {
+ constexpr int event_types[] = {
+ int(SDL_MOUSEBUTTONDOWN),
+ int(SDL_MOUSEBUTTONUP) };
+ subscribe(osd(), event_types);
+ }
+
+ osd_printf_verbose("Lightgun: Start initialization\n");
+
+ if (!dual)
+ {
+ auto &devinfo = create_device<sdl_lightgun_device>(
+ DEVICE_CLASS_LIGHTGUN,
+ "System pointer gun 1",
+ "System pointer gun 1");
+ osd_printf_verbose("Lightgun: Registered %s\n", devinfo.name());
+ }
+ else
+ {
+ auto &dev1info = create_device<sdl_dual_lightgun_device>(
+ DEVICE_CLASS_LIGHTGUN,
+ "System pointer gun 1",
+ "System pointer gun 1",
+ 0);
+ osd_printf_verbose("Lightgun: Registered %s\n", dev1info.name());
+
+ auto &dev2info = create_device<sdl_dual_lightgun_device>(
+ DEVICE_CLASS_LIGHTGUN,
+ "System pointer gun 2",
+ "System pointer gun 2",
+ 1);
+ osd_printf_verbose("Lightgun: Registered %s\n", dev2info.name());
+ }
+
+ osd_printf_verbose("Lightgun: End initialization\n");
+ }
+};
+
+
+//============================================================
// sdl_joystick_module_base
//============================================================
@@ -2201,10 +2463,7 @@ protected:
char guid_str[256];
guid_str[0] = '\0';
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
- char const *serial = nullptr;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
- serial = SDL_JoystickGetSerial(joy);
-#endif
+ char const *const serial = SDL_JoystickGetSerial(joy);
std::string id(guid_str);
if (serial)
id.append(1, '-').append(serial);
@@ -2316,7 +2575,7 @@ public:
for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
create_joystick_device(physical_stick, sixaxis_mode);
- static int const event_types[] = {
+ constexpr int event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@@ -2341,10 +2600,7 @@ public:
else
{
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
- char const *serial = nullptr;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
- serial = SDL_JoystickGetSerial(joy);
-#endif
+ char const *const serial = SDL_JoystickGetSerial(joy);
auto *const target_device = find_reconnect_match(guid, serial);
if (target_device)
{
@@ -2440,7 +2696,7 @@ public:
create_game_controller_device(physical_stick, ctrl);
}
- static int const joy_event_types[] = {
+ constexpr int joy_event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@@ -2448,7 +2704,7 @@ public:
int(SDL_JOYBUTTONUP),
int(SDL_JOYDEVICEADDED),
int(SDL_JOYDEVICEREMOVED) };
- static int const event_types[] = {
+ constexpr int event_types[] = {
int(SDL_JOYAXISMOTION),
int(SDL_JOYBALLMOTION),
int(SDL_JOYHATMOTION),
@@ -2494,10 +2750,7 @@ public:
}
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
- char const *serial = nullptr;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
- serial = SDL_JoystickGetSerial(joy);
-#endif
+ char const *const serial = SDL_JoystickGetSerial(joy);
auto *const target_device = find_reconnect_match(guid, serial);
if (target_device)
{
@@ -2527,10 +2780,7 @@ public:
}
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(event.cdevice.which);
- char const *serial = nullptr;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
- serial = SDL_GameControllerGetSerial(ctrl);
-#endif
+ char const *const serial = SDL_GameControllerGetSerial(ctrl);
auto *const target_device = find_reconnect_match(guid, serial);
if (target_device)
{
@@ -2562,10 +2812,7 @@ private:
char guid_str[256];
guid_str[0] = '\0';
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
- char const *serial = nullptr;
-#if SDL_VERSION_ATLEAST(2, 0, 14)
- serial = SDL_GameControllerGetSerial(ctrl);
-#endif
+ char const *const serial = SDL_GameControllerGetSerial(ctrl);
std::string id(guid_str);
if (serial)
id.append(1, '-').append(serial);
@@ -2615,6 +2862,7 @@ namespace {
MODULE_NOT_SUPPORTED(sdl_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_mouse_module, OSD_MOUSEINPUT_PROVIDER, "sdl")
+MODULE_NOT_SUPPORTED(sdl_lightgun_module, OSD_LIGHTGUNINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdljoy")
MODULE_NOT_SUPPORTED(sdl_game_controller_module, OSD_JOYSTICKINPUT_PROVIDER, "sdlgame")
@@ -2627,5 +2875,6 @@ MODULE_NOT_SUPPORTED(sdl_game_controller_module, OSD_JOYSTICKINPUT_PROVIDER, "sd
MODULE_DEFINITION(KEYBOARDINPUT_SDL, osd::sdl_keyboard_module)
MODULE_DEFINITION(MOUSEINPUT_SDL, osd::sdl_mouse_module)
+MODULE_DEFINITION(LIGHTGUNINPUT_SDL, osd::sdl_lightgun_module)
MODULE_DEFINITION(JOYSTICKINPUT_SDLJOY, osd::sdl_joystick_module)
MODULE_DEFINITION(JOYSTICKINPUT_SDLGAME, osd::sdl_game_controller_module)