diff options
author | 2024-04-26 06:26:22 +1000 | |
---|---|---|
committer | 2024-04-26 06:26:22 +1000 | |
commit | f91b896cda8343fc41f069b32b7ef527364bdea1 (patch) | |
tree | 105ca2e24d44ae9ceac3f540abf07b4f00086cde /src/osd/modules/input/input_sdl.cpp | |
parent | 3b618bd7f04b8164fbcbb1fc106502e05ee85d6a (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.cpp | 357 |
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) |