From c7478642a61e76c5c595b3b61f74d1a67df8a4aa Mon Sep 17 00:00:00 2001 From: german77 Date: Thu, 15 Jul 2021 13:37:10 -0500 Subject: [PATCH] input_common: Support SDL toggle buttons --- src/input_common/sdl/sdl_impl.cpp | 55 +++++++++++++++++-- .../configuration/configure_input_player.cpp | 3 +- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 68672a92b..a49d93f01 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -115,6 +115,41 @@ public: return state.buttons.at(button); } + bool ToggleButton(int button) { + std::lock_guard lock{mutex}; + + if (!state.toggle_buttons.contains(button) || !state.lock_buttons.contains(button)) { + state.toggle_buttons.insert_or_assign(button, false); + state.lock_buttons.insert_or_assign(button, false); + } + + const bool button_state = state.toggle_buttons.at(button); + const bool button_lock = state.lock_buttons.at(button); + + if (button_lock) { + return button_state; + } + + state.lock_buttons.insert_or_assign(button, true); + + if (button_state) { + state.toggle_buttons.insert_or_assign(button, false); + } else { + state.toggle_buttons.insert_or_assign(button, true); + } + + return !button_state; + } + + bool UnlockButton(int button) { + std::lock_guard lock{mutex}; + if (!state.toggle_buttons.contains(button)) { + return false; + } + state.lock_buttons.insert_or_assign(button, false); + return state.toggle_buttons.at(button); + } + void SetAxis(int axis, Sint16 value) { std::lock_guard lock{mutex}; state.axes.insert_or_assign(axis, value); @@ -241,6 +276,8 @@ public: private: struct State { std::unordered_map buttons; + std::unordered_map toggle_buttons{}; + std::unordered_map lock_buttons{}; std::unordered_map axes; std::unordered_map hats; } state; @@ -402,16 +439,25 @@ void SDLState::CloseJoysticks() { class SDLButton final : public Input::ButtonDevice { public: - explicit SDLButton(std::shared_ptr joystick_, int button_) - : joystick(std::move(joystick_)), button(button_) {} + explicit SDLButton(std::shared_ptr joystick_, int button_, bool toggle_) + : joystick(std::move(joystick_)), button(button_), toggle(toggle_) {} bool GetStatus() const override { - return joystick->GetButton(button); + const bool button_state = joystick->GetButton(button); + if (!toggle) { + return button_state; + } + + if (button_state) { + return joystick->ToggleButton(button); + } + return joystick->UnlockButton(button); } private: std::shared_ptr joystick; int button; + bool toggle; }; class SDLDirectionButton final : public Input::ButtonDevice { @@ -635,6 +681,7 @@ public: std::unique_ptr Create(const Common::ParamPackage& params) override { const std::string guid = params.Get("guid", "0"); const int port = params.Get("port", 0); + const auto toggle = params.Get("toggle", false); auto joystick = state.GetSDLJoystickByGUID(guid, port); @@ -679,7 +726,7 @@ public: const int button = params.Get("button", 0); // This is necessary so accessing GetButton with button won't crash joystick->SetButton(button, false); - return std::make_unique(joystick, button); + return std::make_unique(joystick, button, toggle); } private: diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index d5d624b96..14579c220 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -149,8 +149,9 @@ QString ButtonToText(const Common::ParamPackage& param) { if (param.Has("button")) { const QString button_str = QString::fromStdString(param.Get("button", "")); + const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : ""); - return QObject::tr("Button %1").arg(button_str); + return QObject::tr("%1Button %2").arg(toggle, button_str); } if (param.Has("motion")) {