Merge pull request #6649 from german77/toggle_sdl

input_common: Support SDL toggle buttons
This commit is contained in:
bunnei 2021-07-20 20:35:20 -04:00 committed by GitHub
commit 29fb110049
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 5 deletions

View File

@ -115,6 +115,41 @@ public:
return state.buttons.at(button); 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) { void SetAxis(int axis, Sint16 value) {
std::lock_guard lock{mutex}; std::lock_guard lock{mutex};
state.axes.insert_or_assign(axis, value); state.axes.insert_or_assign(axis, value);
@ -241,6 +276,8 @@ public:
private: private:
struct State { struct State {
std::unordered_map<int, bool> buttons; std::unordered_map<int, bool> buttons;
std::unordered_map<int, bool> toggle_buttons{};
std::unordered_map<int, bool> lock_buttons{};
std::unordered_map<int, Sint16> axes; std::unordered_map<int, Sint16> axes;
std::unordered_map<int, Uint8> hats; std::unordered_map<int, Uint8> hats;
} state; } state;
@ -402,16 +439,25 @@ void SDLState::CloseJoysticks() {
class SDLButton final : public Input::ButtonDevice { class SDLButton final : public Input::ButtonDevice {
public: public:
explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_, bool toggle_)
: joystick(std::move(joystick_)), button(button_) {} : joystick(std::move(joystick_)), button(button_), toggle(toggle_) {}
bool GetStatus() const override { 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: private:
std::shared_ptr<SDLJoystick> joystick; std::shared_ptr<SDLJoystick> joystick;
int button; int button;
bool toggle;
}; };
class SDLDirectionButton final : public Input::ButtonDevice { class SDLDirectionButton final : public Input::ButtonDevice {
@ -635,6 +681,7 @@ public:
std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override { std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override {
const std::string guid = params.Get("guid", "0"); const std::string guid = params.Get("guid", "0");
const int port = params.Get("port", 0); const int port = params.Get("port", 0);
const auto toggle = params.Get("toggle", false);
auto joystick = state.GetSDLJoystickByGUID(guid, port); auto joystick = state.GetSDLJoystickByGUID(guid, port);
@ -679,7 +726,7 @@ public:
const int button = params.Get("button", 0); const int button = params.Get("button", 0);
// This is necessary so accessing GetButton with button won't crash // This is necessary so accessing GetButton with button won't crash
joystick->SetButton(button, false); joystick->SetButton(button, false);
return std::make_unique<SDLButton>(joystick, button); return std::make_unique<SDLButton>(joystick, button, toggle);
} }
private: private:

View File

@ -149,8 +149,9 @@ QString ButtonToText(const Common::ParamPackage& param) {
if (param.Has("button")) { if (param.Has("button")) {
const QString button_str = QString::fromStdString(param.Get("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")) { if (param.Has("motion")) {