From 95060efb7dbc5e7671be47f2d2e4a19932a34134 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 22 May 2023 20:49:22 +0200 Subject: [PATCH] input: add support for multi-assignment in emulated pads --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 47 +++++++++++++++++++----------- rpcs3/Emu/Io/Buzz.cpp | 9 +++--- rpcs3/Emu/Io/GHLtar.cpp | 38 +++++++++++++++--------- rpcs3/Emu/Io/Turntable.cpp | 38 +++++++++++++++--------- rpcs3/Emu/Io/emulated_pad_config.h | 15 +++++----- rpcs3/Emu/Io/usio.cpp | 7 +++-- 6 files changed, 98 insertions(+), 56 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index c1d19b5bb6..f1dc0123fc 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -678,13 +678,14 @@ static void ds3_input_to_pad(const u32 port_no, be_t& digital_buttons, be_t for (const Button& button : pad->m_buttons) { if (!button.m_pressed) - { continue; - } - if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value()) + for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode)) { - switch (btn.value()->btn_id()) + if (!btn) + continue; + + switch (btn->btn_id()) { case gem_btn::start: digital_buttons |= CELL_GEM_CTRL_START; @@ -733,9 +734,32 @@ static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr& std::function handle_input; handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis) { - if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value()) + const auto& btns = cfg->find_button(offset, keycode); + if (btns.empty()) { - switch (btn.value()->btn_id()) + if (check_axis) + { + switch (offset) + { + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: + handle_input(offset, static_cast(axis_direction::both), value, false); + break; + default: + break; + } + } + return; + } + + for (const auto& btn : btns) + { + if (!btn) + continue; + + switch (btn->btn_id()) { case gem_btn::x_axis: x_pos = value; @@ -747,17 +771,6 @@ static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr& break; } } - else if (check_axis) - { - switch (offset) - { - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - default: break; - } - } }; for (const AnalogStick& stick : pad->m_sticks) diff --git a/rpcs3/Emu/Io/Buzz.cpp b/rpcs3/Emu/Io/Buzz.cpp index e038031956..386a03eb27 100644 --- a/rpcs3/Emu/Io/Buzz.cpp +++ b/rpcs3/Emu/Io/Buzz.cpp @@ -107,13 +107,14 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/ for (const Button& button : pad->m_buttons) { if (!button.m_pressed) - { continue; - } - if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value()) + for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode)) { - switch (btn.value()->btn_id()) + if (!btn) + continue; + + switch (btn->btn_id()) { case buzz_btn::red: buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red diff --git a/rpcs3/Emu/Io/GHLtar.cpp b/rpcs3/Emu/Io/GHLtar.cpp index 026e64655a..c5925bd1f2 100644 --- a/rpcs3/Emu/Io/GHLtar.cpp +++ b/rpcs3/Emu/Io/GHLtar.cpp @@ -150,9 +150,32 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint std::function handle_input; handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis) { - if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value()) + const auto& btns = cfg->find_button(offset, keycode); + if (btns.empty()) { - switch (btn.value()->btn_id()) + if (check_axis) + { + switch (offset) + { + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: + handle_input(offset, static_cast(axis_direction::both), value, false); + break; + default: + break; + } + } + return; + } + + for (const auto& btn : btns) + { + if (!btn) + continue; + + switch (btn->btn_id()) { case ghltar_btn::w1: buf[0] += 0x01; // W1 @@ -207,17 +230,6 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint break; } } - else if (check_axis) - { - switch (offset) - { - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - default: break; - } - } }; for (const Button& button : pad->m_buttons) diff --git a/rpcs3/Emu/Io/Turntable.cpp b/rpcs3/Emu/Io/Turntable.cpp index 52d4fc4a9e..437b12eafa 100644 --- a/rpcs3/Emu/Io/Turntable.cpp +++ b/rpcs3/Emu/Io/Turntable.cpp @@ -162,9 +162,32 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo std::function handle_input; handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis) { - if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value()) + const auto& btns = cfg->find_button(offset, keycode); + if (btns.empty()) { - switch (btn.value()->btn_id()) + if (check_axis) + { + switch (offset) + { + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: + handle_input(offset, static_cast(axis_direction::both), value, false); + break; + default: + break; + } + } + return; + } + + for (const auto& btn : btns) + { + if (!btn) + continue; + + switch (btn->btn_id()) { case turntable_btn::blue: buf[0] |= 0x01; // Square Button @@ -284,17 +307,6 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo break; } } - else if (check_axis) - { - switch (offset) - { - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast(axis_direction::both), value, false); break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast(axis_direction::both), value, false); break; - default: break; - } - } }; for (const Button& button : pad->m_buttons) diff --git a/rpcs3/Emu/Io/emulated_pad_config.h b/rpcs3/Emu/Io/emulated_pad_config.h index f8d206c603..cd8d5d57d5 100644 --- a/rpcs3/Emu/Io/emulated_pad_config.h +++ b/rpcs3/Emu/Io/emulated_pad_config.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include LOG_CHANNEL(cfg_log, "CFG"); @@ -34,19 +34,20 @@ struct emulated_pad_config : cfg::node using cfg::node::node; std::vector*> buttons; - std::map*>> button_map; + std::map*>>> button_map; - std::optional*> find_button(u32 offset, u32 keycode) const + const std::set*>& find_button(u32 offset, u32 keycode) const { if (const auto it = button_map.find(offset); it != button_map.cend()) { - if (const auto it2 = it->second.find(keycode); it2 != it->second.cend() && it2->second) + if (const auto it2 = it->second.find(keycode); it2 != it->second.cend() && !it2->second.empty()) { return it2->second; } } - - return std::nullopt; + + static const std::set*> empty_set; + return empty_set; } cfg_pad_btn* get_button(T id) @@ -85,7 +86,7 @@ struct emulated_pad_config : cfg::node if (!pbtn) return; const u32 offset = pad_button_offset(pbtn->get()); const u32 keycode = pad_button_keycode(pbtn->get()); - button_map[(offset >> 8) & 0xFF][keycode & 0xFF] = std::as_const(pbtn); + button_map[(offset >> 8) & 0xFF][keycode & 0xFF].insert(std::as_const(pbtn)); buttons.push_back(pbtn); } diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index 4bb51da8fa..32fd084f81 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -201,9 +201,12 @@ void usb_device_usio::translate_input() for (const Button& button : pad->m_buttons) { - if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value()) + for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode)) { - switch (btn.value()->btn_id()) + if (!btn) + continue; + + switch (btn->btn_id()) { case usio_btn::test: if (player != 0) break;