From 7e03828f35f7447d9cca38739ecc52c6cd397c87 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 18:20:33 +0100 Subject: [PATCH 1/5] input: Allow mapping keys to basic mouse buttons --- rpcs3/Emu/Io/MouseHandler.cpp | 2 +- rpcs3/Input/basic_mouse_handler.cpp | 44 ++++++++++++++----- rpcs3/Input/basic_mouse_handler.h | 14 ++++-- rpcs3/rpcs3qt/basic_mouse_settings_dialog.cpp | 20 +++++++++ rpcs3/rpcs3qt/basic_mouse_settings_dialog.h | 1 + 5 files changed, 64 insertions(+), 17 deletions(-) diff --git a/rpcs3/Emu/Io/MouseHandler.cpp b/rpcs3/Emu/Io/MouseHandler.cpp index 0194d8e7e9..b6c09bcb0d 100644 --- a/rpcs3/Emu/Io/MouseHandler.cpp +++ b/rpcs3/Emu/Io/MouseHandler.cpp @@ -34,7 +34,7 @@ void MouseHandlerBase::save(utils::serial& ar) bool MouseHandlerBase::is_time_for_update(double elapsed_time) { steady_clock::time_point now = steady_clock::now(); - double elapsed = (now - last_update).count() / 1000'000.; + const double elapsed = (now - last_update).count() / 1000'000.; if (elapsed > elapsed_time) { diff --git a/rpcs3/Input/basic_mouse_handler.cpp b/rpcs3/Input/basic_mouse_handler.cpp index d9435ef95e..30eed46cbd 100644 --- a/rpcs3/Input/basic_mouse_handler.cpp +++ b/rpcs3/Input/basic_mouse_handler.cpp @@ -108,10 +108,10 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev) switch (ev->type()) { case QEvent::MouseButtonPress: - MouseButtonDown(static_cast(ev)); + MouseButton(static_cast(ev), true); break; case QEvent::MouseButtonRelease: - MouseButtonUp(static_cast(ev)); + MouseButton(static_cast(ev), false); break; case QEvent::MouseMove: MouseMove(static_cast(ev)); @@ -119,6 +119,12 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev) case QEvent::Wheel: MouseScroll(static_cast(ev)); break; + case QEvent::KeyPress: + Key(static_cast(ev), true); + break; + case QEvent::KeyRelease: + Key(static_cast(ev), false); + break; default: return false; } @@ -126,22 +132,22 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev) return false; } -void basic_mouse_handler::MouseButtonDown(QMouseEvent* event) +void basic_mouse_handler::Key(QKeyEvent* event, bool pressed) { if (!event) [[unlikely]] { return; } - const int button = event->button(); - if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second == button; }); + const int key = event->key(); + if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [key](const auto& entry){ return entry.second.code == key && entry.second.is_key; }); it != m_buttons.cend()) { - MouseHandlerBase::Button(0, it->first, true); + MouseHandlerBase::Button(0, it->first, pressed); } } -void basic_mouse_handler::MouseButtonUp(QMouseEvent* event) +void basic_mouse_handler::MouseButton(QMouseEvent* event, bool pressed) { if (!event) [[unlikely]] { @@ -149,10 +155,10 @@ void basic_mouse_handler::MouseButtonUp(QMouseEvent* event) } const int button = event->button(); - if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second == button; }); + if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second.code == button && !entry.second.is_key; }); it != m_buttons.cend()) { - MouseHandlerBase::Button(0, it->first, false); + MouseHandlerBase::Button(0, it->first, pressed); } } @@ -176,17 +182,31 @@ bool basic_mouse_handler::get_mouse_lock_state() const return false; } -int basic_mouse_handler::get_mouse_button(const cfg::string& button) +basic_mouse_handler::mouse_button basic_mouse_handler::get_mouse_button(const cfg::string& button) { const std::string name = button.to_string(); const auto it = std::find_if(mouse_list.cbegin(), mouse_list.cend(), [&name](const auto& entry){ return entry.second == name; }); if (it != mouse_list.cend()) { - return it->first; + return mouse_button{ + .code = static_cast(it->first), + .is_key = false + }; } - return Qt::MouseButton::NoButton; + if (const u32 key = keyboard_pad_handler::GetKeyCode(QString::fromStdString(name))) + { + return mouse_button{ + .code = static_cast(key), + .is_key = true + }; + } + + return mouse_button{ + .code = Qt::MouseButton::NoButton, + .is_key = false + }; } void basic_mouse_handler::MouseMove(QMouseEvent* event) diff --git a/rpcs3/Input/basic_mouse_handler.h b/rpcs3/Input/basic_mouse_handler.h index ccd4224bd8..2c5b58ab80 100644 --- a/rpcs3/Input/basic_mouse_handler.h +++ b/rpcs3/Input/basic_mouse_handler.h @@ -20,8 +20,8 @@ public: void Init(const u32 max_connect) override; void SetTargetWindow(QWindow* target); - void MouseButtonDown(QMouseEvent* event); - void MouseButtonUp(QMouseEvent* event); + void Key(QKeyEvent* event, bool pressed); + void MouseButton(QMouseEvent* event, bool pressed); void MouseScroll(QWheelEvent* event); void MouseMove(QMouseEvent* event); @@ -29,8 +29,14 @@ public: private: void reload_config(); bool get_mouse_lock_state() const; - static int get_mouse_button(const cfg::string& button); + + struct mouse_button + { + int code = Qt::MouseButton::NoButton; + bool is_key = false; + }; + static mouse_button get_mouse_button(const cfg::string& button); QWindow* m_target = nullptr; - std::map m_buttons; + std::map m_buttons; }; diff --git a/rpcs3/rpcs3qt/basic_mouse_settings_dialog.cpp b/rpcs3/rpcs3qt/basic_mouse_settings_dialog.cpp index f56ec6ec5c..e98d2798a4 100644 --- a/rpcs3/rpcs3qt/basic_mouse_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/basic_mouse_settings_dialog.cpp @@ -190,6 +190,26 @@ void basic_mouse_settings_dialog::on_button_click(int id) m_remap_timer.start(1000); } +void basic_mouse_settings_dialog::keyPressEvent(QKeyEvent* event) +{ + if (m_button_id < 0) + { + // We are not remapping a button, so pass the event to the base class. + QDialog::keyPressEvent(event); + return; + } + + const std::string name = keyboard_pad_handler::GetKeyName(event, false); + g_cfg_mouse.get_button(m_button_id).from_string(name); + + if (auto button = m_buttons->button(m_button_id)) + { + button->setText(QString::fromStdString(name)); + } + + reactivate_buttons(); +} + void basic_mouse_settings_dialog::mouseReleaseEvent(QMouseEvent* event) { if (m_button_id < 0) diff --git a/rpcs3/rpcs3qt/basic_mouse_settings_dialog.h b/rpcs3/rpcs3qt/basic_mouse_settings_dialog.h index ab7dd48450..c432143185 100644 --- a/rpcs3/rpcs3qt/basic_mouse_settings_dialog.h +++ b/rpcs3/rpcs3qt/basic_mouse_settings_dialog.h @@ -39,6 +39,7 @@ private: QTimer m_remap_timer; protected: + void keyPressEvent(QKeyEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override; }; From a0df1e09a655f980e10a6a636b5916686b97cdcf Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 21:10:28 +0100 Subject: [PATCH 2/5] ps move: allow to configure mouse move handler buttons --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 134 +++++++++++++----- rpcs3/Emu/Io/Buzz.cpp | 2 +- rpcs3/Emu/Io/GHLtar.cpp | 2 +- rpcs3/Emu/Io/GunCon3.cpp | 2 +- rpcs3/Emu/Io/TopShotElite.cpp | 2 +- rpcs3/Emu/Io/TopShotFearmaster.cpp | 2 +- rpcs3/Emu/Io/Turntable.cpp | 2 +- rpcs3/Emu/Io/emulated_pad_config.h | 34 +++-- rpcs3/Emu/Io/gem_config.h | 43 +++++- rpcs3/Emu/Io/usio.cpp | 4 +- .../rpcs3qt/emulated_pad_settings_dialog.cpp | 98 +++++++++++-- rpcs3/rpcs3qt/emulated_pad_settings_dialog.h | 1 + rpcs3/rpcs3qt/main_window.cpp | 6 + rpcs3/rpcs3qt/main_window.ui | 6 + 14 files changed, 273 insertions(+), 65 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index 48d609120f..22988d25e6 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -40,9 +40,18 @@ void fmt_class_string::format(std::string& out, u64 arg) case gem_btn::square: return "Square"; case gem_btn::move: return "Move"; case gem_btn::t: return "T"; - case gem_btn::count: return "Count"; case gem_btn::x_axis: return "X-Axis"; case gem_btn::y_axis: return "Y-Axis"; + case gem_btn::combo: return "Combo"; + case gem_btn::combo_start: return "Combo Start"; + case gem_btn::combo_select: return "Combo Select"; + case gem_btn::combo_triangle: return "Combo Triangle"; + case gem_btn::combo_circle: return "Combo Circle"; + case gem_btn::combo_cross: return "Combo Cross"; + case gem_btn::combo_square: return "Combo Square"; + case gem_btn::combo_move: return "Combo Move"; + case gem_btn::combo_t: return "Combo T"; + case gem_btn::count: return "Count"; } return unknown; @@ -177,6 +186,7 @@ using gun_thread = named_thread; cfg_gems g_cfg_gem_real; cfg_fake_gems g_cfg_gem_fake; +cfg_mouse_gems g_cfg_gem_mouse; struct gem_config_data { @@ -494,8 +504,14 @@ public: cellGem.notice("Could not load fake gem config. Using defaults."); } + if (!g_cfg_gem_mouse.load()) + { + cellGem.notice("Could not load mouse gem config. Using defaults."); + } + cellGem.notice("Real gem config=\n", g_cfg_gem_real.to_string()); cellGem.notice("Fake gem config=\n", g_cfg_gem_fake.to_string()); + cellGem.notice("Mouse gem config=\n", g_cfg_gem_mouse.to_string()); } }; @@ -1574,7 +1590,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t& digital_buttons, be_t return; } - const auto handle_input = [&](gem_btn btn, u16 value, bool pressed) + const auto handle_input = [&](gem_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; @@ -1606,9 +1622,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t& digital_buttons, be_t digital_buttons |= CELL_GEM_CTRL_T; analog_t = std::max(analog_t, value); break; - case gem_btn::x_axis: - case gem_btn::y_axis: - case gem_btn::count: + default: break; } }; @@ -1632,7 +1646,7 @@ static inline void ds3_get_stick_values(u32 gem_num, const std::shared_ptr& y_pos = 0; const auto& cfg = ::at32(g_cfg_gem_fake.players, gem_num); - cfg->handle_input(pad, true, [&](gem_btn btn, u16 value, bool pressed) + cfg->handle_input(pad, true, [&](gem_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; @@ -1828,41 +1842,97 @@ static bool mouse_input_to_pad(u32 mouse_no, be_t& digital_buttons, be_t pressed_buttons; const Mouse& mouse_data = ::at32(handler.GetMice(), mouse_no); - const auto is_pressed = [&mouse_data, &pressed_buttons](MouseButtonCodes button) -> bool + auto& cfg = ::at32(g_cfg_gem_mouse.players, mouse_no); + + bool combo_active = false; + std::set combos; + + static const std::unordered_map btn_map = { - // Only allow each button to be used for one action unless it's the combo button. - return (mouse_data.buttons & button) && (button == (CELL_MOUSE_BUTTON_3 + 0u/*fix warning*/) || pressed_buttons.insert(button).second); + { gem_btn::start, CELL_GEM_CTRL_START }, + { gem_btn::select, CELL_GEM_CTRL_SELECT }, + { gem_btn::triangle, CELL_GEM_CTRL_TRIANGLE }, + { gem_btn::circle, CELL_GEM_CTRL_CIRCLE }, + { gem_btn::cross, CELL_GEM_CTRL_CROSS }, + { gem_btn::square, CELL_GEM_CTRL_SQUARE }, + { gem_btn::move, CELL_GEM_CTRL_MOVE }, + { gem_btn::t, CELL_GEM_CTRL_T }, + { gem_btn::combo_start, CELL_GEM_CTRL_START }, + { gem_btn::combo_select, CELL_GEM_CTRL_SELECT }, + { gem_btn::combo_triangle, CELL_GEM_CTRL_TRIANGLE }, + { gem_btn::combo_circle, CELL_GEM_CTRL_CIRCLE }, + { gem_btn::combo_cross, CELL_GEM_CTRL_CROSS }, + { gem_btn::combo_square, CELL_GEM_CTRL_SQUARE }, + { gem_btn::combo_move, CELL_GEM_CTRL_MOVE }, + { gem_btn::combo_t, CELL_GEM_CTRL_T }, }; - digital_buttons = 0; + // Check combo button first + cfg->handle_input(mouse_data, [&combo_active](gem_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& abort) + { + if (pressed && btn == gem_btn::combo) + { + combo_active = true; + abort = true; + } + }); - if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_1)) || is_pressed(CELL_MOUSE_BUTTON_6)) - digital_buttons |= CELL_GEM_CTRL_SELECT; + // Check combos + if (combo_active) + { + cfg->handle_input(mouse_data, [&digital_buttons, &combos](gem_btn btn, pad_button pad_btn, u16 /*value*/, bool pressed, bool& /*abort*/) + { + if (!pressed) + return; - if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_2)) || is_pressed(CELL_MOUSE_BUTTON_7)) - digital_buttons |= CELL_GEM_CTRL_START; + switch (btn) + { + case gem_btn::combo_start: + case gem_btn::combo_select: + case gem_btn::combo_triangle: + case gem_btn::combo_circle: + case gem_btn::combo_cross: + case gem_btn::combo_square: + case gem_btn::combo_move: + case gem_btn::combo_t: + digital_buttons |= ::at32(btn_map, btn); + combos.insert(pad_btn); + break; + default: + break; + } + }); + } - if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_4)) || is_pressed(CELL_MOUSE_BUTTON_8)) - digital_buttons |= CELL_GEM_CTRL_TRIANGLE; + // Check normal buttons + cfg->handle_input(mouse_data, [&digital_buttons, &combos](gem_btn btn, pad_button pad_btn, u16 /*value*/, bool pressed, bool& /*abort*/) + { + if (!pressed) + return; - if (is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_5)) - digital_buttons |= CELL_GEM_CTRL_SQUARE; + switch (btn) + { + case gem_btn::start: + case gem_btn::select: + case gem_btn::square: + case gem_btn::cross: + case gem_btn::circle: + case gem_btn::triangle: + case gem_btn::move: + case gem_btn::t: + // Ignore this gem_btn if the same pad_button was already used in a combo + if (!combos.contains(pad_btn)) + { + digital_buttons |= ::at32(btn_map, btn); + } + break; + default: + break; + } + }); - if (is_pressed(CELL_MOUSE_BUTTON_1)) - digital_buttons |= CELL_GEM_CTRL_T; - - if (is_pressed(CELL_MOUSE_BUTTON_2)) - digital_buttons |= CELL_GEM_CTRL_MOVE; - - if (is_pressed(CELL_MOUSE_BUTTON_4)) - digital_buttons |= CELL_GEM_CTRL_CIRCLE; - - if (is_pressed(CELL_MOUSE_BUTTON_5)) - digital_buttons |= CELL_GEM_CTRL_CROSS; - - analog_t = (mouse_data.buttons & CELL_MOUSE_BUTTON_1) ? 0xFFFF : 0; + analog_t = (digital_buttons & CELL_GEM_CTRL_T) ? 0xFFFF : 0; return true; } diff --git a/rpcs3/Emu/Io/Buzz.cpp b/rpcs3/Emu/Io/Buzz.cpp index 06cdc2f064..108bdec0ab 100644 --- a/rpcs3/Emu/Io/Buzz.cpp +++ b/rpcs3/Emu/Io/Buzz.cpp @@ -161,7 +161,7 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/ } const auto& cfg = g_cfg_buzz.players[i]; - cfg->handle_input(pad, true, [&buf, &index](buzz_btn btn, u16 /*value*/, bool pressed) + cfg->handle_input(pad, true, [&buf, &index](buzz_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/GHLtar.cpp b/rpcs3/Emu/Io/GHLtar.cpp index 140c8e3a98..d6fe87e9fc 100644 --- a/rpcs3/Emu/Io/GHLtar.cpp +++ b/rpcs3/Emu/Io/GHLtar.cpp @@ -147,7 +147,7 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint } const auto& cfg = ::at32(g_cfg_ghltar.players, m_controller_index); - cfg->handle_input(pad, true, [&buf](ghltar_btn btn, u16 value, bool pressed) + cfg->handle_input(pad, true, [&buf](ghltar_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/GunCon3.cpp b/rpcs3/Emu/Io/GunCon3.cpp index ee9694447c..7eef591ecc 100644 --- a/rpcs3/Emu/Io/GunCon3.cpp +++ b/rpcs3/Emu/Io/GunCon3.cpp @@ -227,7 +227,7 @@ void usb_device_guncon3::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, return; } - const auto input_callback = [&gc](guncon3_btn btn, u16 value, bool pressed) + const auto input_callback = [&gc](guncon3_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/TopShotElite.cpp b/rpcs3/Emu/Io/TopShotElite.cpp index 0d85cfd5fa..b170027a9f 100644 --- a/rpcs3/Emu/Io/TopShotElite.cpp +++ b/rpcs3/Emu/Io/TopShotElite.cpp @@ -280,7 +280,7 @@ void usb_device_topshotelite::interrupt_transfer(u32 buf_size, u8* buf, u32 /*en } bool up = false, right = false, down = false, left = false; - const auto input_callback = [&ts, &up, &down, &left, &right](topshotelite_btn btn, u16 value, bool pressed) + const auto input_callback = [&ts, &up, &down, &left, &right](topshotelite_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/TopShotFearmaster.cpp b/rpcs3/Emu/Io/TopShotFearmaster.cpp index bfae945365..aba831fa9c 100644 --- a/rpcs3/Emu/Io/TopShotFearmaster.cpp +++ b/rpcs3/Emu/Io/TopShotFearmaster.cpp @@ -308,7 +308,7 @@ void usb_device_topshotfearmaster::interrupt_transfer(u32 buf_size, u8* buf, u32 } bool up = false, right = false, down = false, left = false; - const auto input_callback = [&ts, &up, &down, &left, &right](topshotfearmaster_btn btn, u16 value, bool pressed) + const auto input_callback = [&ts, &up, &down, &left, &right](topshotfearmaster_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/Turntable.cpp b/rpcs3/Emu/Io/Turntable.cpp index af5648d40b..63bb815a1d 100644 --- a/rpcs3/Emu/Io/Turntable.cpp +++ b/rpcs3/Emu/Io/Turntable.cpp @@ -159,7 +159,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo return; const auto& cfg = ::at32(g_cfg_turntable.players, m_controller_index); - cfg->handle_input(pad, true, [&buf](turntable_btn btn, u16 value, bool pressed) + cfg->handle_input(pad, true, [&buf](turntable_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/) { if (!pressed) return; diff --git a/rpcs3/Emu/Io/emulated_pad_config.h b/rpcs3/Emu/Io/emulated_pad_config.h index b6703b01dd..3b0887459c 100644 --- a/rpcs3/Emu/Io/emulated_pad_config.h +++ b/rpcs3/Emu/Io/emulated_pad_config.h @@ -88,7 +88,7 @@ public: button_map.clear(); } - void handle_input(std::shared_ptr pad, bool press_only, const std::function& func) const + void handle_input(std::shared_ptr pad, bool press_only, const std::function& func) const { if (!pad) return; @@ -97,19 +97,25 @@ public: { if (button.m_pressed || !press_only) { - handle_input(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true); + if (handle_input(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true)) + { + return; + } } } for (const AnalogStick& stick : pad->m_sticks) { - handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true); + if (handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true)) + { + return; + } } } - void handle_input(const Mouse& mouse, const std::function& func) const + void handle_input(const Mouse& mouse, const std::function& func) const { - for (int i = 0; i < 7; i++) + for (int i = 0; i < 8; i++) { const MouseButtonCodes cell_code = get_mouse_button_code(i); if ((mouse.buttons & cell_code)) @@ -117,7 +123,11 @@ public: const pad_button button = static_cast(static_cast(pad_button::mouse_button_1) + i); const u32 offset = pad_button_offset(button); const u32 keycode = pad_button_keycode(button); - handle_input(func, offset, keycode, 255, true, true); + + if (handle_input(func, offset, keycode, 255, true, true)) + { + return; + } } } } @@ -163,10 +173,12 @@ protected: return empty_set; } - void handle_input(const std::function& func, u32 offset, u32 keycode, u16 value, bool pressed, bool check_axis) const + bool handle_input(const std::function& func, u32 offset, u32 keycode, u16 value, bool pressed, bool check_axis) const { m_mutex.lock(); + bool abort = false; + const auto& btns = find_button(offset, keycode); if (btns.empty()) { @@ -180,24 +192,26 @@ protected: 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(func, offset, static_cast(axis_direction::both), value, pressed, false); + abort = handle_input(func, offset, static_cast(axis_direction::both), value, pressed, false); break; default: break; } } - return; + return abort; } for (const auto& btn : btns) { if (btn && func) { - func(btn->btn_id(), value, pressed); + func(btn->btn_id(), btn->get(), value, pressed, abort); + if (abort) break; } } m_mutex.unlock(); + return abort; } }; diff --git a/rpcs3/Emu/Io/gem_config.h b/rpcs3/Emu/Io/gem_config.h index d737928790..2be86ff3c4 100644 --- a/rpcs3/Emu/Io/gem_config.h +++ b/rpcs3/Emu/Io/gem_config.h @@ -4,7 +4,7 @@ #include -enum class gem_btn +enum class gem_btn : u32 { start, select, @@ -17,6 +17,18 @@ enum class gem_btn x_axis, y_axis, + combo_begin, + combo = combo_begin, + combo_start, + combo_select, + combo_triangle, + combo_circle, + combo_cross, + combo_square, + combo_move, + combo_t, + combo_end = combo_t, + count }; @@ -41,6 +53,34 @@ struct cfg_fake_gems final : public emulated_pads_config cfg_fake_gems() : emulated_pads_config("gem") {}; }; +struct cfg_mouse_gem final : public emulated_pad_config +{ + cfg_mouse_gem(node* owner, const std::string& name) : emulated_pad_config(owner, name) {} + + cfg_pad_btn start{ this, "Start", gem_btn::start, pad_button::mouse_button_6 }; + cfg_pad_btn select{ this, "Select", gem_btn::select, pad_button::mouse_button_7 }; + cfg_pad_btn triangle{ this, "Triangle", gem_btn::triangle, pad_button::mouse_button_8 }; + cfg_pad_btn circle{ this, "Circle", gem_btn::circle, pad_button::mouse_button_4 }; + cfg_pad_btn cross{ this, "Cross", gem_btn::cross, pad_button::mouse_button_5 }; + cfg_pad_btn square{ this, "Square", gem_btn::square, pad_button::mouse_button_3 }; + cfg_pad_btn move{ this, "Move", gem_btn::move, pad_button::mouse_button_2 }; + cfg_pad_btn t{ this, "T", gem_btn::t, pad_button::mouse_button_1 }; + cfg_pad_btn combo{ this, "Combo", gem_btn::combo, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_start{ this, "Combo Start", gem_btn::combo_start, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_select{ this, "Combo Select", gem_btn::combo_select, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_triangle{ this, "Combo Triangle", gem_btn::combo_triangle, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_circle{ this, "Combo Circle", gem_btn::combo_circle, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_cross{ this, "Combo Cross", gem_btn::combo_cross, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_square{ this, "Combo Square", gem_btn::combo_square, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_move{ this, "Combo Move", gem_btn::combo_move, pad_button::pad_button_max_enum }; + cfg_pad_btn combo_t{ this, "Combo T", gem_btn::combo_t, pad_button::pad_button_max_enum }; +}; + +struct cfg_mouse_gems final : public emulated_pads_config +{ + cfg_mouse_gems() : emulated_pads_config("gem_mouse") {}; +}; + struct cfg_gem final : public emulated_pad_config { cfg_gem(node* owner, const std::string& name) : emulated_pad_config(owner, name) {} @@ -62,3 +102,4 @@ struct cfg_gems final : public emulated_pads_config extern cfg_gems g_cfg_gem_real; extern cfg_fake_gems g_cfg_gem_fake; +extern cfg_mouse_gems g_cfg_gem_mouse; diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index 7dea19c8fb..faecec177d 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -203,7 +203,7 @@ void usb_device_usio::translate_input_taiko() if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed()) { const auto& cfg = ::at32(g_cfg_usio.players, pad_number); - cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed) + cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/) { switch (btn) { @@ -288,7 +288,7 @@ void usb_device_usio::translate_input_tekken() if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed()) { const auto& cfg = ::at32(g_cfg_usio.players, pad_number); - cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed) + cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/) { switch (btn) { diff --git a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp index 835f940797..a3fcde1e82 100644 --- a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp @@ -92,6 +92,10 @@ emulated_pad_settings_dialog::emulated_pad_settings_dialog(pad_type type, QWidge setWindowTitle(tr("Configure Emulated PS Move (Fake)")); add_tabs(tabs); break; + case emulated_pad_settings_dialog::pad_type::mousegem: + setWindowTitle(tr("Configure Emulated PS Move (Mouse)")); + add_tabs(tabs); + break; case emulated_pad_settings_dialog::pad_type::guncon3: setWindowTitle(tr("Configure Emulated GunCon 3")); add_tabs(tabs); @@ -116,8 +120,12 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) { ensure(!!tabs); - constexpr u32 max_items_per_column = 6; - int count = static_cast(T::count); + std::set ignored_values; + + const auto remove_value = [&ignored_values](int value) + { + ignored_values.insert(static_cast(value)); + }; usz players = 0; switch (m_type) @@ -137,13 +145,29 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) case pad_type::gem: players = g_cfg_gem_real.players.size(); - // Ignore x and y axis - static_assert(static_cast(gem_btn::y_axis) == static_cast(gem_btn::count) - 1); - static_assert(static_cast(gem_btn::x_axis) == static_cast(gem_btn::count) - 2); - count -= 2; + // Ignore combo, x and y axis + remove_value(static_cast(gem_btn::x_axis)); + remove_value(static_cast(gem_btn::y_axis)); + for (int i = static_cast(gem_btn::combo_begin); i <= static_cast(gem_btn::combo_end); i++) + { + remove_value(i); + } break; case pad_type::ds3gem: players = g_cfg_gem_fake.players.size(); + + // Ignore combo + for (int i = static_cast(gem_btn::combo_begin); i <= static_cast(gem_btn::combo_end); i++) + { + remove_value(i); + } + break; + case pad_type::mousegem: + players = g_cfg_gem_mouse.players.size(); + + // Ignore x and y axis + remove_value(static_cast(gem_btn::x_axis)); + remove_value(static_cast(gem_btn::y_axis)); break; case pad_type::guncon3: players = g_cfg_guncon3.players.size(); @@ -156,6 +180,8 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) break; } + constexpr u32 max_items_per_column = 6; + const int count = static_cast(T::count) - static_cast(ignored_values.size()); int rows = count; for (u32 cols = 1; utils::aligned_div(static_cast(count), cols) > max_items_per_column;) @@ -170,8 +196,10 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) QWidget* widget = new QWidget(this); QGridLayout* grid_layout = new QGridLayout(this); - for (int i = 0, row = 0, col = 0; i < count; i++, row++) + for (int i = 0, row = 0, col = 0; i < static_cast(T::count); i++) { + if (ignored_values.contains(i)) continue; + const T id = static_cast(i); const QString name = QString::fromStdString(fmt::format("%s", id)); @@ -179,16 +207,35 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) QGroupBox* gb = new QGroupBox(name, this); QComboBox* combo = new QComboBox; - for (int p = 0; p < static_cast(pad_button::pad_button_max_enum); p++) + if constexpr (std::is_same_v) { - const QString translated = localized_emu::translated_pad_button(static_cast(p)); - combo->addItem(translated); - const int index = combo->findText(translated); - combo->setItemData(index, p, button_role::button); - combo->setItemData(index, i, button_role::emulated_button); + const gem_btn btn = static_cast(i); + if (btn >= gem_btn::combo_begin && btn <= gem_btn::combo_end) + { + gb->setToolTip(tr("Press the \"Combo\" button in combination with any of the other combo buttons to trigger their related PS Move button.\n" + "This can be useful if your device does not have enough regular buttons.")); + } } - if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + // Add empty value + combo->addItem(""); + const int index = combo->findText(""); + combo->setItemData(index, static_cast(pad_button::pad_button_max_enum), button_role::button); + combo->setItemData(index, i, button_role::emulated_button); + + if (m_type != pad_type::mousegem) + { + for (int p = 0; p < static_cast(pad_button::pad_button_max_enum); p++) + { + const QString translated = localized_emu::translated_pad_button(static_cast(p)); + combo->addItem(translated); + const int index = combo->findText(translated); + combo->setItemData(index, p, button_role::button); + combo->setItemData(index, i, button_role::emulated_button); + } + } + + if (std::is_same_v || std::is_same_v || std::is_same_v || m_type == pad_type::mousegem) { for (int p = static_cast(pad_button::mouse_button_1); p <= static_cast(pad_button::mouse_button_8); p++) { @@ -221,6 +268,9 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) case pad_type::ds3gem: saved_btn_id = ::at32(g_cfg_gem_fake.players, player)->get_pad_button(static_cast(id)); break; + case pad_type::mousegem: + saved_btn_id = ::at32(g_cfg_gem_mouse.players, player)->get_pad_button(static_cast(id)); + break; case pad_type::guncon3: saved_btn_id = ::at32(g_cfg_guncon3.players, player)->get_pad_button(static_cast(id)); break; @@ -265,6 +315,9 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) case pad_type::ds3gem: ::at32(g_cfg_gem_fake.players, player)->set_button(static_cast(id), btn_id); break; + case pad_type::mousegem: + ::at32(g_cfg_gem_mouse.players, player)->set_button(static_cast(id), btn_id); + break; case pad_type::guncon3: ::at32(g_cfg_guncon3.players, player)->set_button(static_cast(id), btn_id); break; @@ -287,6 +340,8 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) h_layout->addWidget(combo); gb->setLayout(h_layout); grid_layout->addWidget(gb, row, col); + + row++; } widget->setLayout(grid_layout); @@ -334,6 +389,12 @@ void emulated_pad_settings_dialog::load_config() cfg_log.notice("Could not load fake gem config. Using defaults."); } break; + case emulated_pad_settings_dialog::pad_type::mousegem: + if (!g_cfg_gem_mouse.load()) + { + cfg_log.notice("Could not load mouse gem config. Using defaults."); + } + break; case emulated_pad_settings_dialog::pad_type::guncon3: if (!g_cfg_guncon3.load()) { @@ -377,6 +438,9 @@ void emulated_pad_settings_dialog::save_config() case emulated_pad_settings_dialog::pad_type::ds3gem: g_cfg_gem_fake.save(); break; + case emulated_pad_settings_dialog::pad_type::mousegem: + g_cfg_gem_mouse.save(); + break; case emulated_pad_settings_dialog::pad_type::guncon3: g_cfg_guncon3.save(); break; @@ -411,6 +475,9 @@ void emulated_pad_settings_dialog::reset_config() case emulated_pad_settings_dialog::pad_type::ds3gem: g_cfg_gem_fake.from_default(); break; + case emulated_pad_settings_dialog::pad_type::mousegem: + g_cfg_gem_mouse.from_default(); + break; case emulated_pad_settings_dialog::pad_type::guncon3: g_cfg_guncon3.from_default(); break; @@ -454,6 +521,9 @@ void emulated_pad_settings_dialog::reset_config() case pad_type::ds3gem: def_btn_id = ::at32(g_cfg_gem_fake.players, player)->default_pad_button(static_cast(data.toInt())); break; + case pad_type::mousegem: + def_btn_id = ::at32(g_cfg_gem_mouse.players, player)->default_pad_button(static_cast(data.toInt())); + break; case pad_type::guncon3: def_btn_id = ::at32(g_cfg_guncon3.players, player)->default_pad_button(static_cast(data.toInt())); break; diff --git a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h index 772f467182..ad1b863d7e 100644 --- a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h +++ b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.h @@ -21,6 +21,7 @@ public: usio, gem, ds3gem, + mousegem, guncon3, topshotelite, topshotfearmaster, diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index 46e056e43a..b4bc2af5d6 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -2911,6 +2911,12 @@ void main_window::CreateConnects() dlg->show(); }); + connect(ui->confPSMoveMouseAct, &QAction::triggered, this, [this] + { + emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::mousegem, this); + dlg->show(); + }); + connect(ui->confPSMoveDS3Act, &QAction::triggered, this, [this] { emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::ds3gem, this); diff --git a/rpcs3/rpcs3qt/main_window.ui b/rpcs3/rpcs3qt/main_window.ui index ba29696974..adb66d8bcf 100644 --- a/rpcs3/rpcs3qt/main_window.ui +++ b/rpcs3/rpcs3qt/main_window.ui @@ -244,6 +244,7 @@ + @@ -1333,6 +1334,11 @@ PS Move (Fake) + + + PS Move (Mouse) + + GunCon 3 From b8d0396f71719dbe52a88aa6faf030d0a5bf41d8 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 22:00:31 +0100 Subject: [PATCH 3/5] Fix self assignment warning --- rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp b/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp index 8213b29a2d..5d66ae87d0 100644 --- a/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/Trophies/overlay_trophy_list_dialog.cpp @@ -265,7 +265,6 @@ namespace rsx fade_animation.end = color4f(1.f); fade_animation.active = true; - this->on_close = std::move(on_close); visible = true; const auto notify = std::make_shared>(0); From d6f2f66f2b38a4d068cff2877243337dc4f9e01c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 22:33:44 +0100 Subject: [PATCH 4/5] Qt/Input: use empty string for pad_button_max_enum Also shorten translated mouse button strings --- rpcs3/Emu/Io/pad_types.cpp | 2 +- rpcs3/rpcs3qt/localized_emu.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Io/pad_types.cpp b/rpcs3/Emu/Io/pad_types.cpp index 46d1f284d7..428e0d6cea 100644 --- a/rpcs3/Emu/Io/pad_types.cpp +++ b/rpcs3/Emu/Io/pad_types.cpp @@ -39,7 +39,7 @@ void fmt_class_string::format(std::string& out, u64 arg) case pad_button::rs_right: return "Right Stick Right"; case pad_button::rs_x: return "Right Stick X-Axis"; case pad_button::rs_y: return "Right Stick Y-Axis"; - case pad_button::pad_button_max_enum: return "MAX_ENUM"; + case pad_button::pad_button_max_enum: return ""; case pad_button::mouse_button_1: return "Mouse Button 1"; case pad_button::mouse_button_2: return "Mouse Button 2"; case pad_button::mouse_button_3: return "Mouse Button 3"; diff --git a/rpcs3/rpcs3qt/localized_emu.cpp b/rpcs3/rpcs3qt/localized_emu.cpp index 4fb2b4b9f9..bfc0b52101 100644 --- a/rpcs3/rpcs3qt/localized_emu.cpp +++ b/rpcs3/rpcs3qt/localized_emu.cpp @@ -36,14 +36,14 @@ QString localized_emu::translated_pad_button(pad_button btn) case pad_button::rs_x: return tr("Right Stick X-Axis"); case pad_button::rs_y: return tr("Right Stick Y-Axis"); case pad_button::pad_button_max_enum: return ""; - case pad_button::mouse_button_1: return tr("Mouse Button 1"); - case pad_button::mouse_button_2: return tr("Mouse Button 2"); - case pad_button::mouse_button_3: return tr("Mouse Button 3"); - case pad_button::mouse_button_4: return tr("Mouse Button 4"); - case pad_button::mouse_button_5: return tr("Mouse Button 5"); - case pad_button::mouse_button_6: return tr("Mouse Button 6"); - case pad_button::mouse_button_7: return tr("Mouse Button 7"); - case pad_button::mouse_button_8: return tr("Mouse Button 8"); + case pad_button::mouse_button_1: return tr("Mouse 1"); + case pad_button::mouse_button_2: return tr("Mouse 2"); + case pad_button::mouse_button_3: return tr("Mouse 3"); + case pad_button::mouse_button_4: return tr("Mouse 4"); + case pad_button::mouse_button_5: return tr("Mouse 5"); + case pad_button::mouse_button_6: return tr("Mouse 6"); + case pad_button::mouse_button_7: return tr("Mouse 7"); + case pad_button::mouse_button_8: return tr("Mouse 8"); } return ""; } From 061be74cdb07ed4fdef8b7e649d76b5024661de5 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 23:32:27 +0100 Subject: [PATCH 5/5] Qt: add mouse config legend to mouse move dialog --- rpcs3/Input/raw_mouse_config.cpp | 2 + rpcs3/Input/raw_mouse_config.h | 2 - .../rpcs3qt/emulated_pad_settings_dialog.cpp | 71 ++++++++++++++++++- rpcs3/rpcs3qt/raw_mouse_settings_dialog.cpp | 2 + 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/rpcs3/Input/raw_mouse_config.cpp b/rpcs3/Input/raw_mouse_config.cpp index b02f349dac..0d896fc1d8 100644 --- a/rpcs3/Input/raw_mouse_config.cpp +++ b/rpcs3/Input/raw_mouse_config.cpp @@ -2,6 +2,8 @@ #include "raw_mouse_config.h" #include "Emu/Io/MouseHandler.h" +LOG_CHANNEL(cfg_log, "CFG"); + std::string mouse_button_id(int code) { switch (code) diff --git a/rpcs3/Input/raw_mouse_config.h b/rpcs3/Input/raw_mouse_config.h index b1ae83883d..902e0ed42f 100644 --- a/rpcs3/Input/raw_mouse_config.h +++ b/rpcs3/Input/raw_mouse_config.h @@ -5,8 +5,6 @@ #include -LOG_CHANNEL(cfg_log, "CFG"); - std::string mouse_button_id(int code); struct raw_mouse_config : cfg::node diff --git a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp index a3fcde1e82..00520a8c7c 100644 --- a/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/emulated_pad_settings_dialog.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" #include "emulated_pad_settings_dialog.h" #include "localized_emu.h" +#include "Input/raw_mouse_config.h" +#include "Emu/Io/mouse_config.h" #include "Emu/Io/buzz_config.h" #include "Emu/Io/gem_config.h" #include "Emu/Io/ghltar_config.h" @@ -13,6 +15,7 @@ #include #include +#include #include #include #include @@ -191,9 +194,24 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) m_combos.resize(players); + const bool show_mouse_legend = m_type == pad_type::mousegem; + + if (show_mouse_legend) + { + if (!g_cfg_mouse.load()) + { + cfg_log.notice("Could not restore mouse config. Using defaults."); + } + + if (!g_cfg_raw_mouse.load()) + { + cfg_log.notice("Could not restore raw mouse config. Using defaults."); + } + } + for (usz player = 0; player < players; player++) { - QWidget* widget = new QWidget(this); + // Create grid with all buttons QGridLayout* grid_layout = new QGridLayout(this); for (int i = 0, row = 0, col = 0; i < static_cast(T::count); i++) @@ -344,7 +362,56 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs) row++; } - widget->setLayout(grid_layout); + QVBoxLayout* v_layout = new QVBoxLayout(this); + + // Create a legend of the current mouse settings + if (show_mouse_legend) + { + QHBoxLayout* legend_layout = new QHBoxLayout(this); + if (player == 0) + { + std::string basic_mouse_settings; + fmt::append(basic_mouse_settings, "1: %s\n", g_cfg_mouse.mouse_button_1.to_string()); + fmt::append(basic_mouse_settings, "2: %s\n", g_cfg_mouse.mouse_button_2.to_string()); + fmt::append(basic_mouse_settings, "3: %s\n", g_cfg_mouse.mouse_button_3.to_string()); + fmt::append(basic_mouse_settings, "4: %s\n", g_cfg_mouse.mouse_button_4.to_string()); + fmt::append(basic_mouse_settings, "5: %s\n", g_cfg_mouse.mouse_button_5.to_string()); + fmt::append(basic_mouse_settings, "6: %s\n", g_cfg_mouse.mouse_button_6.to_string()); + fmt::append(basic_mouse_settings, "7: %s\n", g_cfg_mouse.mouse_button_7.to_string()); + fmt::append(basic_mouse_settings, "8: %s", g_cfg_mouse.mouse_button_8.to_string()); + + QGroupBox* gb_legend_basic = new QGroupBox(tr("Current Basic Mouse Config"), this); + QVBoxLayout* gb_legend_basic_layout = new QVBoxLayout(this); + gb_legend_basic_layout->addWidget(new QLabel(QString::fromStdString(basic_mouse_settings), this)); + gb_legend_basic->setLayout(gb_legend_basic_layout); + legend_layout->addWidget(gb_legend_basic); + } + { + std::string raw_mouse_settings; + const auto& raw_cfg = *ensure(::at32(g_cfg_raw_mouse.players, player)); + fmt::append(raw_mouse_settings, "1: %s\n", raw_cfg.mouse_button_1.to_string()); + fmt::append(raw_mouse_settings, "2: %s\n", raw_cfg.mouse_button_2.to_string()); + fmt::append(raw_mouse_settings, "3: %s\n", raw_cfg.mouse_button_3.to_string()); + fmt::append(raw_mouse_settings, "4: %s\n", raw_cfg.mouse_button_4.to_string()); + fmt::append(raw_mouse_settings, "5: %s\n", raw_cfg.mouse_button_5.to_string()); + fmt::append(raw_mouse_settings, "6: %s\n", raw_cfg.mouse_button_6.to_string()); + fmt::append(raw_mouse_settings, "7: %s\n", raw_cfg.mouse_button_7.to_string()); + fmt::append(raw_mouse_settings, "8: %s", raw_cfg.mouse_button_8.to_string()); + + QGroupBox* gb_legend_raw = new QGroupBox(tr("Current Raw Mouse Config"), this); + QVBoxLayout* gb_legend_raw_layout = new QVBoxLayout(this); + gb_legend_raw_layout->addWidget(new QLabel(QString::fromStdString(raw_mouse_settings), this)); + gb_legend_raw->setLayout(gb_legend_raw_layout); + legend_layout->addWidget(gb_legend_raw); + } + v_layout->addLayout(legend_layout); + } + + v_layout->addLayout(grid_layout); + + QWidget* widget = new QWidget(this); + widget->setLayout(v_layout); + tabs->addTab(widget, tr("Player %0").arg(player + 1)); } } diff --git a/rpcs3/rpcs3qt/raw_mouse_settings_dialog.cpp b/rpcs3/rpcs3qt/raw_mouse_settings_dialog.cpp index 3cfccb9755..31151e098e 100644 --- a/rpcs3/rpcs3qt/raw_mouse_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/raw_mouse_settings_dialog.cpp @@ -11,6 +11,8 @@ #include #include +LOG_CHANNEL(cfg_log, "CFG"); + constexpr u32 button_count = 8; raw_mouse_settings_dialog::raw_mouse_settings_dialog(QWidget* parent)