summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_sdl.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2024-04-26 06:26:22 +1000
committer Vas Crabb <vas@vastheman.com>2024-04-26 06:26:22 +1000
commitf91b896cda8343fc41f069b32b7ef527364bdea1 (patch)
tree105ca2e24d44ae9ceac3f540abf07b4f00086cde /src/osd/modules/input/input_sdl.cpp
parent3b618bd7f04b8164fbcbb1fc106502e05ee85d6a (diff)
input/input_sdl.cpp: Added an SDL lightgun provider.
This does essentially the same thing as the Win32 lightgun provider, mapping the absolute pointer position over the window to gun axes. Also added a bunch of const in the windows input handling code. docs: Bumped version, as features that are not in a releaesd version of MAME are now documented.
Diffstat (limited to 'src/osd/modules/input/input_sdl.cpp')
-rw-r--r--src/osd/modules/input/input_sdl.cpp357
1 files changed, 316 insertions, 41 deletions
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 62e13cbf960..1be07a3a429 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -642,29 +642,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);
}
@@ -673,12 +662,28 @@ public:
virtual void reset() override
{
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
+ {
+ 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 the axes
+ // add horizontal and vertical axes - relative for a mouse or absolute for a gun
device.add_item(
"X",
std::string_view(),
@@ -691,6 +696,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(),
@@ -703,36 +764,125 @@ public:
ITEM_ID_RZAXIS,
generic_axis_get_state<s32>,
&m_mouse.lH);
+ }
- // add the buttons
- for (int button = 0; button < 4; button++)
+ virtual void process_event(SDL_Event const &event) override
+ {
+ switch (event.type)
{
- 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]);
+ 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);
+
+ SDL_Window *const win(m_window ? SDL_GetWindowFromID(m_window) : nullptr);
+ if (win)
+ {
+ 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:
@@ -745,19 +895,75 @@ public:
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;
};
@@ -1955,7 +2161,7 @@ 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) };
@@ -2079,7 +2285,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),
@@ -2102,6 +2308,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
//============================================================
@@ -2284,7 +2557,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),
@@ -2405,7 +2678,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),
@@ -2413,7 +2686,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),
@@ -2571,6 +2844,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")
@@ -2583,5 +2857,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)