From 062f67529a69c3f6bcfda77927b31b09a4832807 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 9 Jan 2025 18:20:33 +0100 Subject: [PATCH] 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; };