From 2898be69f414a2735b8693c58e039097853f5ec7 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Tue, 6 Sep 2022 11:20:53 -0500
Subject: [PATCH 1/2] input_common: Add support for analog toggle

---
 src/common/input.h                                | 5 +++++
 src/core/hid/input_converter.cpp                  | 3 +++
 src/input_common/input_poller.cpp                 | 1 +
 src/yuzu/configuration/configure_input_player.cpp | 6 ++++++
 4 files changed, 15 insertions(+)

diff --git a/src/common/input.h b/src/common/input.h
index 213aa2384d..825b0d650d 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -102,6 +102,8 @@ struct AnalogProperties {
     float offset{};
     // Invert direction of the sensor data
     bool inverted{};
+    // Press once to activate, press again to release
+    bool toggle{};
 };
 
 // Single analog sensor data
@@ -115,8 +117,11 @@ struct AnalogStatus {
 struct ButtonStatus {
     Common::UUID uuid{};
     bool value{};
+    // Invert value of the button
     bool inverted{};
+    // Press once to activate, press again to release
     bool toggle{};
+    // Internal lock for the toggle status
     bool locked{};
 };
 
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index 68d143a013..52fb69e9c8 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -52,6 +52,9 @@ Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatu
     Common::Input::ButtonStatus status{};
     switch (callback.type) {
     case Common::Input::InputType::Analog:
+        status.value = TransformToTrigger(callback).pressed.value;
+        status.toggle = callback.analog_status.properties.toggle;
+        break;
     case Common::Input::InputType::Trigger:
         status.value = TransformToTrigger(callback).pressed.value;
         break;
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
index 133422d5cd..ffb9b945e5 100644
--- a/src/input_common/input_poller.cpp
+++ b/src/input_common/input_poller.cpp
@@ -824,6 +824,7 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
         .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
         .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
         .inverted = params.Get("invert", "+") == "-",
+        .toggle = static_cast<bool>(params.Get("toggle", false)),
     };
     input_engine->PreSetController(identifier);
     input_engine->PreSetAxis(identifier, axis);
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 109689c88d..972c311f60 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -382,6 +382,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
                             button_map[button_id]->setText(ButtonToText(param));
                             emulated_controller->SetButtonParam(button_id, param);
                         });
+                        context_menu.addAction(tr("Toggle axis"), [&] {
+                            const bool toggle_value = !param.Get("toggle", false);
+                            param.Set("toggle", toggle_value);
+                            button_map[button_id]->setText(ButtonToText(param));
+                            emulated_controller->SetButtonParam(button_id, param);
+                        });
                         context_menu.addAction(tr("Set threshold"), [&] {
                             const int button_threshold =
                                 static_cast<int>(param.Get("threshold", 0.5f) * 100.0f);

From de8f7e12509440d4fb2af20432d14e71612a4cba Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Tue, 6 Sep 2022 11:44:29 -0500
Subject: [PATCH 2/2] yuzu: input: fix invert symbol on axis and order options
 alphabetically

---
 .../configuration/configure_input_player.cpp  | 27 ++++++++++---------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 972c311f60..9b4f765cee 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -161,6 +161,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
 
     const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
     const QString inverted = QString::fromStdString(param.Get("inverted", false) ? "!" : "");
+    const QString invert = QString::fromStdString(param.Get("invert", "+") == "-" ? "-" : "");
     const auto common_button_name = input_subsystem->GetButtonName(param);
 
     // Retrieve the names from Qt
@@ -184,7 +185,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
         }
         if (param.Has("axis")) {
             const QString axis = QString::fromStdString(param.Get("axis", ""));
-            return QObject::tr("%1%2Axis %3").arg(toggle, inverted, axis);
+            return QObject::tr("%1%2Axis %3").arg(toggle, invert, axis);
         }
         if (param.Has("axis_x") && param.Has("axis_y") && param.Has("axis_z")) {
             const QString axis_x = QString::fromStdString(param.Get("axis_x", ""));
@@ -362,18 +363,18 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
                         button_map[button_id]->setText(tr("[not set]"));
                     });
                     if (param.Has("code") || param.Has("button") || param.Has("hat")) {
-                        context_menu.addAction(tr("Toggle button"), [&] {
-                            const bool toggle_value = !param.Get("toggle", false);
-                            param.Set("toggle", toggle_value);
-                            button_map[button_id]->setText(ButtonToText(param));
-                            emulated_controller->SetButtonParam(button_id, param);
-                        });
                         context_menu.addAction(tr("Invert button"), [&] {
                             const bool invert_value = !param.Get("inverted", false);
                             param.Set("inverted", invert_value);
                             button_map[button_id]->setText(ButtonToText(param));
                             emulated_controller->SetButtonParam(button_id, param);
                         });
+                        context_menu.addAction(tr("Toggle button"), [&] {
+                            const bool toggle_value = !param.Get("toggle", false);
+                            param.Set("toggle", toggle_value);
+                            button_map[button_id]->setText(ButtonToText(param));
+                            emulated_controller->SetButtonParam(button_id, param);
+                        });
                     }
                     if (param.Has("axis")) {
                         context_menu.addAction(tr("Invert axis"), [&] {
@@ -382,12 +383,6 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
                             button_map[button_id]->setText(ButtonToText(param));
                             emulated_controller->SetButtonParam(button_id, param);
                         });
-                        context_menu.addAction(tr("Toggle axis"), [&] {
-                            const bool toggle_value = !param.Get("toggle", false);
-                            param.Set("toggle", toggle_value);
-                            button_map[button_id]->setText(ButtonToText(param));
-                            emulated_controller->SetButtonParam(button_id, param);
-                        });
                         context_menu.addAction(tr("Set threshold"), [&] {
                             const int button_threshold =
                                 static_cast<int>(param.Get("threshold", 0.5f) * 100.0f);
@@ -404,6 +399,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
                             }
                             emulated_controller->SetButtonParam(button_id, param);
                         });
+                        context_menu.addAction(tr("Toggle axis"), [&] {
+                            const bool toggle_value = !param.Get("toggle", false);
+                            param.Set("toggle", toggle_value);
+                            button_map[button_id]->setText(ButtonToText(param));
+                            emulated_controller->SetButtonParam(button_id, param);
+                        });
                     }
                     context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
                 });