From f91b896cda8343fc41f069b32b7ef527364bdea1 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 26 Apr 2024 06:26:22 +1000 Subject: [PATCH] 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. --- docs/source/commandline/commandline-all.rst | 71 ++-- docs/source/commandline/commandline-index.rst | 6 +- docs/source/commandline/sdlconfig.rst | 17 + docs/source/conf.py | 4 +- src/osd/modules/input/input_rawinput.cpp | 10 +- src/osd/modules/input/input_sdl.cpp | 361 +++++++++++++++--- src/osd/modules/input/input_win32.cpp | 12 +- src/osd/modules/input/input_windows.cpp | 2 +- src/osd/modules/input/input_windows.h | 2 +- src/osd/modules/lib/osdobj_common.cpp | 1 + src/osd/sdl/sdlopts.cpp | 1 + src/osd/sdl/sdlopts.h | 2 + src/osd/windows/window.cpp | 65 ++-- src/osd/windows/winmain.h | 2 +- 14 files changed, 428 insertions(+), 128 deletions(-) diff --git a/docs/source/commandline/commandline-all.rst b/docs/source/commandline/commandline-all.rst index 89f7dac1287..fe093cc0d86 100644 --- a/docs/source/commandline/commandline-all.rst +++ b/docs/source/commandline/commandline-all.rst @@ -775,24 +775,24 @@ OSD-related Options * - **Microsoft Windows** - win - dwrite - - none - auto - - - sdl [#UIFPSDLWindows]_. + - sdl [#UIFPSDLWindows]_ + - none * - **macOS** - - - - none - auto - osx - sdl + - none * - **Linux** - - - - none - auto - - sdl + - none .. rubric:: Footnotes @@ -816,26 +816,19 @@ Example: :stub-columns: 0 * - **Microsoft Windows** - - auto [#KBIPAutoWindows]_. + - auto [#KBIPAutoWindows]_ - rawinput - dinput - win32 + - sdl [#KBIPSDLWindows]_ - none - - sdl [#KBIPSDLWindows]_. * - **SDL (macOS and Linux)** - - auto [#KBIPAutoSDL]_. + - auto [#KBIPAutoSDL]_ - - - - - none - sdl - * - **Linux** - - auto [#KBIPAutoSDL]_. - - - - - - - none - - sdl .. rubric:: Footnotes @@ -868,26 +861,19 @@ Example: :stub-columns: 0 * - **Microsoft Windows** - - auto [#MIPAutoWindows]_. + - auto [#MIPAutoWindows]_ - rawinput - dinput - win32 + - sdl [#MIPSDLWindows]_ - none - - sdl [#MIPSDLWindows]_. * - **SDL (macOS and Linux)** - - auto [#MIPAutoSDL]_. + - auto [#MIPAutoSDL]_ - - - - - none - sdl - * - **Linux** - - auto [#MIPAutoSDL]_. - - - - - - - none - - sdl .. rubric:: Footnotes @@ -916,36 +902,37 @@ Example: :stub-columns: 0 * - **Microsoft Windows** - - auto [#LGIPAutoWindows]_. + - auto [#LGIPAutoWindows]_ - rawinput - win32 + - sdl [#LGIPSDLWindows]_ + - - none - - - - * - **macOS** - - auto [#LGIPAutoSDL]_. + - auto [#LGIPAutoSDL]_ - - + - sdl + - - none - - - - * - **Linux** - - auto [#LGIPAutoLinux]_. + - auto [#LGIPAutoSDL]_ - - - - none - - + - sdl - x11 + - none .. rubric:: Footnotes .. [#LGIPAutoWindows] On Windows, auto will try ``rawinput`` with fallback to ``win32``, or ``none`` if it doesn't find any. -.. [#LGIPAutoSDL] On non-Linux SDL, ``auto`` will default to ``none``. +.. [#LGIPSDLWindows] SDL support on Windows requires that you compile MAME with + the support in. By default SDL is not included in Windows + builds of MAME. -.. [#LGIPAutoLinux] On SDL/Linux, ``auto`` will default to ``x11``, or ``none`` - if it doesn't find any. +.. [#LGIPAutoSDL] On SDL, ``auto`` will default to ``sdl``. Example: .. code-block:: bash @@ -964,15 +951,15 @@ Example: :stub-columns: 0 * - **Microsoft Windows** - - auto [#JIPAutoWindows]_. + - auto [#JIPAutoWindows]_ - winhybrid - dinput - xinput - - sdlgame - - sdljoy + - sdlgame [#JIPSDLWindows]_ + - sdljoy [#JIPSDLWindows]_ - none * - **SDL** - - auto [#JIPAutoSDL]_. + - auto [#JIPAutoSDL]_ - - - @@ -984,6 +971,10 @@ Example: .. [#JIPAutoWindows] On Windows native, auto will default to ``winhybrid``. +.. [#JIPSDLWindows] SDL support on Windows requires that you compile MAME with + the support in. By default SDL is not included in Windows + builds of MAME. + .. [#JIPAutoSDL] On SDL, auto will default to ``sdlgame``. winhybrid diff --git a/docs/source/commandline/commandline-index.rst b/docs/source/commandline/commandline-index.rst index 50500066d6f..c62dfef518b 100644 --- a/docs/source/commandline/commandline-index.rst +++ b/docs/source/commandline/commandline-index.rst @@ -423,10 +423,12 @@ SDL Keyboard Mapping | :ref:`keymap_file ` -SDL Joystick Mapping +SDL Input Options ~~~~~~~~~~~~~~~~~~~~ -| :ref:`sixaxis ` +| :ref:`[no]enable_touch ` +| :ref:`[no]sixaxis ` +| :ref:`[no]dual_lightgun ` SDL Lightgun Mapping diff --git a/docs/source/commandline/sdlconfig.rst b/docs/source/commandline/sdlconfig.rst index df04865a390..3d3582fa69e 100644 --- a/docs/source/commandline/sdlconfig.rst +++ b/docs/source/commandline/sdlconfig.rst @@ -80,6 +80,23 @@ SDL Input Options undesirable behaviour with other controllers. Only affects the ``sdljoy`` joystick provider. Default is OFF (**-nosixaxis**) +.. _mame-scommandline-duallightgun: + +**-[no]dual_lightgun** / **-[no]dual** + + Controls whether or not MAME attempts to track two lightguns that appear as + a single mouse. This option requires the :ref:`lightgun option + ` to be on and the :ref:`lightgunprovider + option ` to be set to *sdl*. + + This option supports dual lightgun setups that work by setting the mouse + pointer location at the moment a lightgun trigger is activated. The primary + and secondary triggers on the first lightgun correspond to the first and + second mouse buttons, and the primary and secondary triggers on the second + lightgun correspond to the third and fourth mouse buttons. + + The default is OFF (**-nodual_lightgun**). + SDL Lightgun Mapping -------------------- diff --git a/docs/source/conf.py b/docs/source/conf.py index 4f5f06b3e52..0b78ef7a53e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -63,9 +63,9 @@ copyright = u'1997-2024, MAMEdev and contributors' # built documents. # # The short X.Y version. -version = '0.265' +version = '0.266' # The full version, including alpha/beta/rc tags. -release = '0.265' +release = '0.266' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 437abf598a4..1bcbb38f781 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -749,14 +749,14 @@ protected: rawinputdevice.hDevice); } - virtual bool handle_input_event(input_event eventid, void *eventdata) override + virtual bool handle_input_event(input_event eventid, void const *eventdata) override { switch (eventid) { // handle raw input data case INPUT_EVENT_RAWINPUT: { - HRAWINPUT const rawinputdevice = *static_cast(eventdata); + HRAWINPUT const rawinputdevice = *reinterpret_cast(eventdata); union { RAWINPUT r; BYTE b[4096]; } small_buffer; std::unique_ptr larger_buffer; @@ -786,7 +786,7 @@ protected: { std::lock_guard scope_lock(m_module_lock); - auto *input = reinterpret_cast(data); + auto *const input = reinterpret_cast(data); if (!input->header.hDevice) return false; @@ -809,7 +809,7 @@ protected: case INPUT_EVENT_ARRIVAL: { - HRAWINPUT const rawinputdevice = *static_cast(eventdata); + HRAWINPUT const rawinputdevice = *reinterpret_cast(eventdata); // determine the length of the device name, allocate it, and fetch it if not nameless UINT name_length = 0; @@ -842,7 +842,7 @@ protected: case INPUT_EVENT_REMOVAL: { - HRAWINPUT const rawinputdevice = *static_cast(eventdata); + HRAWINPUT const rawinputdevice = *reinterpret_cast(eventdata); std::lock_guard scope_lock(m_module_lock); 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 { - // 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(), @@ -691,6 +696,62 @@ public: ITEM_ID_YAXIS, generic_axis_get_state, &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, + &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,19 +764,6 @@ public: ITEM_ID_RZAXIS, generic_axis_get_state, &m_mouse.lH); - - // add the buttons - for (int button = 0; button < 4; 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, - &m_mouse.buttons[offset]); - } } virtual void process_event(SDL_Event const &event) override @@ -749,15 +797,173 @@ public: } private: - // state information for a mouse - struct mouse_state - { - s32 lX, lY, lV, lH; - s32 buttons[MAX_BUTTONS]; - }; + s32 m_x, m_y; +}; - mouse_state m_mouse; - s32 m_x, m_y, m_v, m_h; + +//============================================================ +// 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, + &m_mouse.lV); + device.add_item( + "Scroll H", + std::string_view(), + ITEM_ID_ADD_RELATIVE2, + generic_axis_get_state, + &m_mouse.lH); + } + + virtual void process_event(SDL_Event const &event) override + { + switch (event.type) + { + case SDL_MOUSEMOTION: + 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 += 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; + + case SDL_WINDOWEVENT: + if ((event.window.windowID == m_window) && (SDL_WINDOWEVENT_LEAVE == event.window.event)) + m_window = 0; + break; + } + } + +private: + 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) + { + } + + 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::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), @@ -2101,6 +2307,73 @@ public: }; +//============================================================ +// sdl_lightgun_module +//============================================================ + +class sdl_lightgun_module : public sdl_input_module +{ +public: + sdl_lightgun_module() : sdl_input_module(OSD_LIGHTGUNINPUT_PROVIDER, "sdl") + { + } + + virtual void input_init(running_machine &machine) override + { + auto &sdlopts = dynamic_cast(*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( + 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( + 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( + 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) diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index 49c211740c0..a6740979c16 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -105,14 +105,14 @@ public: create_device(DEVICE_CLASS_KEYBOARD, "Win32 Keyboard 1", "Win32 Keyboard 1"); } - virtual bool handle_input_event(input_event eventid, void *eventdata) override + virtual bool handle_input_event(input_event eventid, void const *eventdata) override { switch (eventid) { case INPUT_EVENT_KEYDOWN: case INPUT_EVENT_KEYUP: devicelist().for_each_device( - [args = static_cast(eventdata)] (auto &device) + [args = reinterpret_cast(eventdata)] (auto &device) { device.queue_events(args, 1); }); @@ -276,13 +276,13 @@ public: create_device(DEVICE_CLASS_MOUSE, "Win32 Mouse 1", "Win32 Mouse 1"); } - virtual bool handle_input_event(input_event eventid, void *eventdata) override + virtual bool handle_input_event(input_event eventid, void const *eventdata) override { if (manager().class_enabled(DEVICE_CLASS_MOUSE)) { if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL)) { - auto const *const args = reinterpret_cast(eventdata); + auto const *const args = reinterpret_cast(eventdata); devicelist().for_each_device( [args] (auto &device) { device.queue_events(args, 1); }); return true; @@ -537,13 +537,13 @@ public: } } - virtual bool handle_input_event(input_event eventid, void *eventdata) override + virtual bool handle_input_event(input_event eventid, void const *eventdata) override { if (manager().class_enabled(DEVICE_CLASS_LIGHTGUN)) { if ((eventid == INPUT_EVENT_MOUSE_BUTTON) || (eventid == INPUT_EVENT_MOUSE_WHEEL)) { - auto const *const args = reinterpret_cast(eventdata); + auto const *const args = reinterpret_cast(eventdata); devicelist().for_each_device( [args] (auto &device) { device.queue_events(args, 1); }); return true; diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp index c635ff0b553..12002ccf893 100644 --- a/src/osd/modules/input/input_windows.cpp +++ b/src/osd/modules/input/input_windows.cpp @@ -40,7 +40,7 @@ bool windows_osd_interface::should_hide_mouse() const return true; } -bool windows_osd_interface::handle_input_event(input_event eventid, void *eventdata) const +bool windows_osd_interface::handle_input_event(input_event eventid, void const *eventdata) const { bool handled = false; diff --git a/src/osd/modules/input/input_windows.h b/src/osd/modules/input/input_windows.h index 175151cb4e5..882f80d053b 100644 --- a/src/osd/modules/input/input_windows.h +++ b/src/osd/modules/input/input_windows.h @@ -31,7 +31,7 @@ protected: virtual ~wininput_event_handler() = default; public: - virtual bool handle_input_event(input_event eventid, void *data) + virtual bool handle_input_event(input_event eventid, void const *data) { return false; } diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index 430f6ceeac9..46a709b415f 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -308,6 +308,7 @@ void osd_common_t::register_options() REGISTER_MODULE(m_mod_man, MOUSEINPUT_WIN32); REGISTER_MODULE(m_mod_man, MOUSE_NONE); + REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_SDL); REGISTER_MODULE(m_mod_man, LIGHTGUN_X11); REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_RAWINPUT); REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32); diff --git a/src/osd/sdl/sdlopts.cpp b/src/osd/sdl/sdlopts.cpp index f08dc41f963..3953a47b7f8 100644 --- a/src/osd/sdl/sdlopts.cpp +++ b/src/osd/sdl/sdlopts.cpp @@ -69,6 +69,7 @@ const options_entry f_sdl_option_entries[] = { nullptr, nullptr, core_options::option_type::HEADER, "SDL INPUT OPTIONS" }, { SDLOPTION_ENABLE_TOUCH, "0", core_options::option_type::BOOLEAN, "enable touch input support" }, { SDLOPTION_SIXAXIS, "0", core_options::option_type::BOOLEAN, "use special handling for PS3 Sixaxis controllers" }, + { SDLOPTION_DUAL_LIGHTGUN ";dual", "0", core_options::option_type::BOOLEAN, "enable dual lightgun input" }, #if (USE_XINPUT) // lightgun mapping diff --git a/src/osd/sdl/sdlopts.h b/src/osd/sdl/sdlopts.h index fe75e097407..f6338fe1db6 100644 --- a/src/osd/sdl/sdlopts.h +++ b/src/osd/sdl/sdlopts.h @@ -28,6 +28,7 @@ #define SDLOPTION_ENABLE_TOUCH "enable_touch" #define SDLOPTION_SIXAXIS "sixaxis" +#define SDLOPTION_DUAL_LIGHTGUN "dual_lightgun" #if defined(USE_XINPUT) && USE_XINPUT #define SDLOPTION_LIGHTGUNINDEX "lightgun_index" #endif @@ -86,6 +87,7 @@ public: // input options bool enable_touch() const { return bool_value(SDLOPTION_ENABLE_TOUCH); } bool sixaxis() const { return bool_value(SDLOPTION_SIXAXIS); } + bool dual_lightgun() const { return bool_value(SDLOPTION_DUAL_LIGHTGUN); } const char *video_driver() const { return value(SDLOPTION_VIDEODRIVER); } const char *render_driver() const { return value(SDLOPTION_RENDERDRIVER); } diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index 690cc90658c..30afd7bc9d3 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -297,7 +297,7 @@ void win_window_info::show_pointer() s_saved_cursor_pos.x = s_saved_cursor_pos.y = -1; } - while (ShowCursor(TRUE) < 1) {}; + while (ShowCursor(TRUE) < 1) { } ShowCursor(FALSE); } @@ -342,7 +342,7 @@ static LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, W // is_mame_window //============================================================ -static bool is_mame_window(HWND hwnd) +inline bool is_mame_window(HWND hwnd) { for (const auto &window : osd_common_t::window_list()) if (dynamic_cast(*window).platform_window() == hwnd) @@ -351,50 +351,50 @@ static bool is_mame_window(HWND hwnd) return false; } -inline static BOOL handle_mouse_button(windows_osd_interface *osd, int button, int down, int x, int y) +inline BOOL handle_mouse_button(windows_osd_interface &osd, int button, int down, LPARAM lparam) { MouseUpdateEventArgs args; args.pressed = (down ? 1 : 0) << button; args.released = (down ? 0 : 1) << button; args.vdelta = 0; args.hdelta = 0; - args.xpos = x; - args.ypos = y; + args.xpos = GET_X_LPARAM(lparam); + args.ypos = GET_Y_LPARAM(lparam); - bool handled = osd->handle_input_event(INPUT_EVENT_MOUSE_BUTTON, &args); + bool const handled = osd.handle_input_event(INPUT_EVENT_MOUSE_BUTTON, &args); // When in lightgun mode or mouse mode, the mouse click may be routed to the input system // because the mouse interactions in the UI are routed from the video_window_proc below // we need to make sure they aren't suppressed in these cases. - return handled && !osd->options().lightgun() && !osd->options().mouse(); + return handled && !osd.options().lightgun() && !osd.options().mouse(); } -inline static BOOL handle_mouse_wheel(windows_osd_interface *osd, int v, int h, int x, int y) +inline BOOL handle_mouse_wheel(windows_osd_interface &osd, int v, int h, LPARAM lparam) { MouseUpdateEventArgs args; args.pressed = 0; args.released = 0; args.vdelta = v; args.hdelta = h; - args.xpos = x; - args.ypos = y; + args.xpos = GET_X_LPARAM(lparam); + args.ypos = GET_Y_LPARAM(lparam); - bool handled = osd->handle_input_event(INPUT_EVENT_MOUSE_WHEEL, &args); + bool const handled = osd.handle_input_event(INPUT_EVENT_MOUSE_WHEEL, &args); // When in lightgun mode or mouse mode, the mouse wheel may be routed to the input system // because the mouse interactions in the UI are routed from the video_window_proc below // we need to make sure they aren't suppressed in these cases. - return handled && !osd->options().lightgun() && !osd->options().mouse(); + return handled && !osd.options().lightgun() && !osd.options().mouse(); } -inline static BOOL handle_keypress(windows_osd_interface *osd, int vkey, int down, int scancode, BOOL extended_key) +inline BOOL handle_keypress(windows_osd_interface &osd, int vkey, int down, LPARAM lparam) { KeyPressEventArgs args; args.event_id = down ? INPUT_EVENT_KEYDOWN : INPUT_EVENT_KEYUP; - args.scancode = MAKE_DI_SCAN(scancode, extended_key); + args.scancode = MAKE_DI_SCAN(SCAN_CODE(lparam), IS_EXTENDED(lparam)); args.vkey = vkey; - return osd->handle_input_event(args.event_id, &args); + return osd.handle_input_event(args.event_id, &args); } //============================================================ @@ -435,54 +435,55 @@ void windows_osd_interface::process_events(bool ingame, bool nodispatch) // forward mouse button downs to the input system case WM_LBUTTONDOWN: - dispatch = !handle_mouse_button(this, 0, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 0, TRUE, message.lParam); break; case WM_RBUTTONDOWN: - dispatch = !handle_mouse_button(this, 1, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 1, TRUE, message.lParam); break; case WM_MBUTTONDOWN: - dispatch = !handle_mouse_button(this, 2, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 2, TRUE, message.lParam); break; case WM_XBUTTONDOWN: - dispatch = !handle_mouse_button(this, 3, TRUE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, (GET_XBUTTON_WPARAM(message.wParam) == XBUTTON1) ? 3 : 4, TRUE, message.lParam); break; // forward mouse button ups to the input system case WM_LBUTTONUP: - dispatch = !handle_mouse_button(this, 0, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 0, FALSE, message.lParam); break; case WM_RBUTTONUP: - dispatch = !handle_mouse_button(this, 1, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 1, FALSE, message.lParam); break; case WM_MBUTTONUP: - dispatch = !handle_mouse_button(this, 2, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, 2, FALSE, message.lParam); break; case WM_XBUTTONUP: - dispatch = !handle_mouse_button(this, 3, FALSE, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_button(*this, (GET_XBUTTON_WPARAM(message.wParam) == XBUTTON1) ? 3 : 4, FALSE, message.lParam); break; // forward mouse wheel movement to the input system case WM_MOUSEWHEEL: - dispatch = !handle_mouse_wheel(this, GET_WHEEL_DELTA_WPARAM(message.wParam), 0, GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_wheel(*this, GET_WHEEL_DELTA_WPARAM(message.wParam), 0, message.lParam); break; case WM_MOUSEHWHEEL: - dispatch = !handle_mouse_wheel(this, 0, GET_WHEEL_DELTA_WPARAM(message.wParam), GET_X_LPARAM(message.lParam), GET_Y_LPARAM(message.lParam)); + dispatch = !handle_mouse_wheel(*this, 0, GET_WHEEL_DELTA_WPARAM(message.wParam), message.lParam); break; + // forward keystrokes to the input system case WM_KEYDOWN: if (NOT_ALREADY_DOWN(message.lParam)) - dispatch = !handle_keypress(this, message.wParam, TRUE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam)); + dispatch = !handle_keypress(*this, message.wParam, TRUE, message.lParam); break; case WM_KEYUP: - dispatch = !handle_keypress(this, message.wParam, FALSE, SCAN_CODE(message.lParam), IS_EXTENDED(message.lParam)); + dispatch = !handle_keypress(*this, message.wParam, FALSE, message.lParam); break; } } @@ -1220,6 +1221,16 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR case WM_POINTERCAPTURECHANGED: window->pointer_capture_changed(wparam, lparam); break; + // TODO: other pointer events? + //case WM_POINTERACTIVATE: + //case WM_POINTERDEVICECHANGE: + //case WM_POINTERDEVICECINRANGE: + //case WM_POINTERDEVICECOUTOFRANGE: + //case WM_POINTERROUTEDAWAY: + //case WM_POINTERROUTEDRELEASED: + //case WM_POINTERROUTEDTO: + //case WM_POINTERWHEEL: + //case WM_POINTERHWHEEL: // pause the system when we start a menu or resize case WM_ENTERSIZEMOVE: diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 2ba8335c175..16bde1ddff4 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -80,7 +80,7 @@ public: void extract_video_config(); // windows OSD specific - bool handle_input_event(input_event eventid, void *eventdata) const; + bool handle_input_event(input_event eventid, const void *eventdata) const; bool should_hide_mouse() const; virtual bool has_focus() const override;