diff options
Diffstat (limited to 'src/osd/modules/input/input_sdl.cpp')
-rw-r--r-- | src/osd/modules/input/input_sdl.cpp | 567 |
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) |