From 746c85b56011b87afb57e37b75953435389fc810 Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sun, 21 Nov 2021 14:12:01 -0600
Subject: [PATCH] input_common: Move button names to the frontend

---
 src/common/input.h                            | 22 +++++
 src/input_common/drivers/gc_adapter.cpp       | 36 ++++----
 src/input_common/drivers/gc_adapter.h         |  4 +-
 src/input_common/drivers/mouse.cpp            |  9 +-
 src/input_common/drivers/mouse.h              |  2 +-
 src/input_common/drivers/sdl_driver.cpp       | 15 ++--
 src/input_common/drivers/sdl_driver.h         |  2 +-
 src/input_common/input_engine.h               |  5 +-
 src/input_common/input_mapping.cpp            |  5 ++
 src/input_common/main.cpp                     | 17 ++--
 src/input_common/main.h                       |  9 +-
 .../configuration/configure_input_player.cpp  | 86 ++++++++++++++++++-
 12 files changed, 160 insertions(+), 52 deletions(-)

diff --git a/src/common/input.h b/src/common/input.h
index d997853c61..cc0cbd9b8a 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -175,6 +175,28 @@ struct LedStatus {
     bool led_4{};
 };
 
+// List of buttons to be passed to Qt that can be translated
+enum class ButtonNames {
+    Undefined,
+    Invalid,
+    // This will display the engine name instead of the button name
+    Engine,
+    // This will display the button by value instead of the button name
+    Value,
+    ButtonLeft,
+    ButtonRight,
+    ButtonDown,
+    ButtonUp,
+    TriggerZ,
+    TriggerR,
+    TriggerL,
+    ButtonA,
+    ButtonB,
+    ButtonX,
+    ButtonY,
+    ButtonStart,
+};
+
 // Callback data consisting of an input type and the equivalent data status
 struct CallbackStatus {
     InputType type{InputType::None};
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp
index a1b9b6d988..8b65742236 100644
--- a/src/input_common/drivers/gc_adapter.cpp
+++ b/src/input_common/drivers/gc_adapter.cpp
@@ -481,47 +481,47 @@ AnalogMapping GCAdapter::GetAnalogMappingForDevice(const Common::ParamPackage& p
     return mapping;
 }
 
-std::string GCAdapter::GetUIButtonName(const Common::ParamPackage& params) const {
+Common::Input::ButtonNames GCAdapter::GetUIButtonName(const Common::ParamPackage& params) const {
     PadButton button = static_cast<PadButton>(params.Get("button", 0));
     switch (button) {
     case PadButton::ButtonLeft:
-        return "left";
+        return Common::Input::ButtonNames::ButtonLeft;
     case PadButton::ButtonRight:
-        return "right";
+        return Common::Input::ButtonNames::ButtonRight;
     case PadButton::ButtonDown:
-        return "down";
+        return Common::Input::ButtonNames::ButtonDown;
     case PadButton::ButtonUp:
-        return "up";
+        return Common::Input::ButtonNames::ButtonUp;
     case PadButton::TriggerZ:
-        return "Z";
+        return Common::Input::ButtonNames::TriggerZ;
     case PadButton::TriggerR:
-        return "R";
+        return Common::Input::ButtonNames::TriggerR;
     case PadButton::TriggerL:
-        return "L";
+        return Common::Input::ButtonNames::TriggerL;
     case PadButton::ButtonA:
-        return "A";
+        return Common::Input::ButtonNames::ButtonA;
     case PadButton::ButtonB:
-        return "B";
+        return Common::Input::ButtonNames::ButtonB;
     case PadButton::ButtonX:
-        return "X";
+        return Common::Input::ButtonNames::ButtonX;
     case PadButton::ButtonY:
-        return "Y";
+        return Common::Input::ButtonNames::ButtonY;
     case PadButton::ButtonStart:
-        return "start";
+        return Common::Input::ButtonNames::ButtonStart;
     default:
-        return "Unknown GC";
+        return Common::Input::ButtonNames::Undefined;
     }
 }
 
-std::string GCAdapter::GetUIName(const Common::ParamPackage& params) const {
+Common::Input::ButtonNames GCAdapter::GetUIName(const Common::ParamPackage& params) const {
     if (params.Has("button")) {
-        return fmt::format("Button {}", GetUIButtonName(params));
+        return GetUIButtonName(params);
     }
     if (params.Has("axis")) {
-        return fmt::format("Axis {}", params.Get("axis", 0));
+        return Common::Input::ButtonNames::Value;
     }
 
-    return "Bad GC Adapter";
+    return Common::Input::ButtonNames::Invalid;
 }
 
 } // namespace InputCommon
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h
index 3e4747040f..8dc51d2e58 100644
--- a/src/input_common/drivers/gc_adapter.h
+++ b/src/input_common/drivers/gc_adapter.h
@@ -34,7 +34,7 @@ public:
     std::vector<Common::ParamPackage> GetInputDevices() const override;
     ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
     AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
-    std::string GetUIName(const Common::ParamPackage& params) const override;
+    Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
 
 private:
     enum class PadButton {
@@ -112,7 +112,7 @@ private:
     /// Updates vibration state of all controllers
     void SendVibrations();
 
-    std::string GetUIButtonName(const Common::ParamPackage& params) const;
+    Common::Input::ButtonNames GetUIButtonName(const Common::ParamPackage& params) const;
 
     std::unique_ptr<LibUSBDeviceHandle> usb_adapter_handle;
     std::array<GCController, 4> pads;
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index 9a9a1987d5..752118e97e 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -171,12 +171,15 @@ AnalogMapping Mouse::GetAnalogMappingForDevice(
     return mapping;
 }
 
-std::string Mouse::GetUIName(const Common::ParamPackage& params) const {
+Common::Input::ButtonNames Mouse::GetUIName(const Common::ParamPackage& params) const {
     if (params.Has("button")) {
-        return fmt::format("Mouse {}", params.Get("button", 0));
+        return Common::Input::ButtonNames::Value;
+    }
+    if (params.Has("axis")) {
+        return Common::Input::ButtonNames::Value;
     }
 
-    return "Bad Mouse";
+    return Common::Input::ButtonNames::Invalid;
 }
 
 } // namespace InputCommon
diff --git a/src/input_common/drivers/mouse.h b/src/input_common/drivers/mouse.h
index 11dd76e140..4a1fd2fd96 100644
--- a/src/input_common/drivers/mouse.h
+++ b/src/input_common/drivers/mouse.h
@@ -63,7 +63,7 @@ public:
 
     std::vector<Common::ParamPackage> GetInputDevices() const override;
     AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
-    std::string GetUIName(const Common::ParamPackage& params) const override;
+    Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
 
 private:
     void UpdateThread(std::stop_token stop_token);
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index d5af6c09b4..90128b6cf6 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -869,26 +869,25 @@ MotionMapping SDLDriver::GetMotionMappingForDevice(const Common::ParamPackage& p
     return mapping;
 }
 
-std::string SDLDriver::GetUIName(const Common::ParamPackage& params) const {
+Common::Input::ButtonNames SDLDriver::GetUIName(const Common::ParamPackage& params) const {
     if (params.Has("button")) {
         // TODO(German77): Find how to substitue the values for real button names
-        return fmt::format("Button {}", params.Get("button", 0));
+        return Common::Input::ButtonNames::Value;
     }
     if (params.Has("hat")) {
-        return fmt::format("Hat {}", params.Get("direction", ""));
+        return Common::Input::ButtonNames::Value;
     }
     if (params.Has("axis")) {
-        return fmt::format("Axis {}", params.Get("axis", ""));
+        return Common::Input::ButtonNames::Value;
     }
     if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
-        return fmt::format("Axis {},{},{}", params.Get("axis_x", ""), params.Get("axis_y", ""),
-                           params.Get("axis_z", ""));
+        return Common::Input::ButtonNames::Value;
     }
     if (params.Has("motion")) {
-        return "SDL motion";
+        return Common::Input::ButtonNames::Engine;
     }
 
-    return "Bad SDL";
+    return Common::Input::ButtonNames::Invalid;
 }
 
 std::string SDLDriver::GetHatButtonName(u8 direction_value) const {
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h
index 3faaca9842..d03ff4b84f 100644
--- a/src/input_common/drivers/sdl_driver.h
+++ b/src/input_common/drivers/sdl_driver.h
@@ -53,7 +53,7 @@ public:
     ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
     AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
     MotionMapping GetMotionMappingForDevice(const Common::ParamPackage& params) override;
-    std::string GetUIName(const Common::ParamPackage& params) const override;
+    Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
 
     std::string GetHatButtonName(u8 direction_value) const override;
     u8 GetHatButtonId(const std::string& direction_name) const override;
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h
index c621686e54..02272b3f87 100644
--- a/src/input_common/input_engine.h
+++ b/src/input_common/input_engine.h
@@ -161,8 +161,9 @@ public:
     };
 
     /// Retrieves the name of the given input.
-    virtual std::string GetUIName([[maybe_unused]] const Common::ParamPackage& params) const {
-        return GetEngineName();
+    virtual Common::Input::ButtonNames GetUIName(
+        [[maybe_unused]] const Common::ParamPackage& params) const {
+        return Common::Input::ButtonNames::Engine;
     };
 
     /// Retrieves the index number of the given hat button direction
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
index 0eeeff3725..c5218f2cb7 100644
--- a/src/input_common/input_mapping.cpp
+++ b/src/input_common/input_mapping.cpp
@@ -61,6 +61,7 @@ void MappingFactory::RegisterButton(const MappingData& data) {
     }
     new_input.Set("port", static_cast<int>(data.pad.port));
     new_input.Set("pad", static_cast<int>(data.pad.pad));
+
     switch (data.type) {
     case EngineInputType::Button:
         // Workaround for old compatibility
@@ -75,6 +76,10 @@ void MappingFactory::RegisterButton(const MappingData& data) {
         new_input.Set("direction", data.hat_name);
         break;
     case EngineInputType::Analog:
+        // Ignore mouse axis when mapping buttons
+        if (data.engine == "mouse") {
+            return;
+        }
         new_input.Set("axis", data.index);
         new_input.Set("threshold", 0.5f);
         break;
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index df36a337c7..39e4935dc1 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -205,9 +205,9 @@ struct InputSubsystem::Impl {
         return {};
     }
 
-    std::string GetButtonName(const Common::ParamPackage& params) const {
+    Common::Input::ButtonNames GetButtonName(const Common::ParamPackage& params) const {
         if (!params.Has("engine") || params.Get("engine", "") == "any") {
-            return "Unknown";
+            return Common::Input::ButtonNames::Undefined;
         }
         const std::string engine = params.Get("engine", "");
         if (engine == mouse->GetEngineName()) {
@@ -227,7 +227,7 @@ struct InputSubsystem::Impl {
             return sdl->GetUIName(params);
         }
 #endif
-        return "Bad engine";
+        return Common::Input::ButtonNames::Invalid;
     }
 
     bool IsController(const Common::ParamPackage& params) {
@@ -361,15 +361,8 @@ MotionMapping InputSubsystem::GetMotionMappingForDevice(const Common::ParamPacka
     return impl->GetMotionMappingForDevice(device);
 }
 
-std::string InputSubsystem::GetButtonName(const Common::ParamPackage& params) const {
-    const std::string toggle = params.Get("toggle", false) ? "~" : "";
-    const std::string inverted = params.Get("inverted", false) ? "!" : "";
-    const std::string button_name = impl->GetButtonName(params);
-    std::string axis_direction = "";
-    if (params.Has("axis")) {
-        axis_direction = params.Get("invert", "+");
-    }
-    return fmt::format("{}{}{}{}", toggle, inverted, button_name, axis_direction);
+Common::Input::ButtonNames InputSubsystem::GetButtonName(const Common::ParamPackage& params) const {
+    return impl->GetButtonName(params);
 }
 
 bool InputSubsystem::IsController(const Common::ParamPackage& params) const {
diff --git a/src/input_common/main.h b/src/input_common/main.h
index a4a24d076e..c6f97f6918 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -13,6 +13,10 @@ namespace Common {
 class ParamPackage;
 }
 
+namespace Common::Input {
+enum class ButtonNames;
+}
+
 namespace Settings::NativeAnalog {
 enum Values : int;
 }
@@ -108,8 +112,9 @@ public:
     /// Retrieves the motion mappings for the given device.
     [[nodiscard]] MotionMapping GetMotionMappingForDevice(const Common::ParamPackage& device) const;
 
-    /// Returns a string contaning the name of the button from the input engine.
-    [[nodiscard]] std::string GetButtonName(const Common::ParamPackage& params) const;
+    /// Returns an enum contaning the name to be displayed from the input engine.
+    [[nodiscard]] Common::Input::ButtonNames GetButtonName(
+        const Common::ParamPackage& params) const;
 
     /// Returns true if device is a controller.
     [[nodiscard]] bool IsController(const Common::ParamPackage& params) const;
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 0254ea6fe1..6219a09a84 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -52,6 +52,37 @@ QString GetKeyName(int key_code) {
     }
 }
 
+QString GetButtonName(Common::Input::ButtonNames button_name) {
+    switch (button_name) {
+    case Common::Input::ButtonNames::ButtonLeft:
+        return QObject::tr("Left");
+    case Common::Input::ButtonNames::ButtonRight:
+        return QObject::tr("Right");
+    case Common::Input::ButtonNames::ButtonDown:
+        return QObject::tr("Down");
+    case Common::Input::ButtonNames::ButtonUp:
+        return QObject::tr("Up");
+    case Common::Input::ButtonNames::TriggerZ:
+        return QObject::tr("Z");
+    case Common::Input::ButtonNames::TriggerR:
+        return QObject::tr("R");
+    case Common::Input::ButtonNames::TriggerL:
+        return QObject::tr("L");
+    case Common::Input::ButtonNames::ButtonA:
+        return QObject::tr("A");
+    case Common::Input::ButtonNames::ButtonB:
+        return QObject::tr("B");
+    case Common::Input::ButtonNames::ButtonX:
+        return QObject::tr("X");
+    case Common::Input::ButtonNames::ButtonY:
+        return QObject::tr("Y");
+    case Common::Input::ButtonNames::ButtonStart:
+        return QObject::tr("Start");
+    default:
+        return QObject::tr("[undefined]");
+    }
+}
+
 void SetAnalogParam(const Common::ParamPackage& input_param, Common::ParamPackage& analog_param,
                     const std::string& button_name) {
     // The poller returned a complete axis, so set all the buttons
@@ -75,15 +106,64 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
         return QObject::tr("[not set]");
     }
 
+    const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
+    const QString inverted = QString::fromStdString(param.Get("inverted", false) ? "!" : "");
+    const auto common_button_name = input_subsystem->GetButtonName(param);
+
     // Retrieve the names from Qt
     if (param.Get("engine", "") == "keyboard") {
         const QString button_str = GetKeyName(param.Get("code", 0));
-        const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
         return QObject::tr("%1%2").arg(toggle, button_str);
     }
 
-    std::string button_name = input_subsystem->GetButtonName(param);
-    return QString::fromStdString(button_name);
+    if (common_button_name == Common::Input::ButtonNames::Invalid) {
+        return QObject::tr("[invalid]");
+    }
+
+    if (common_button_name == Common::Input::ButtonNames::Engine) {
+        return QString::fromStdString(param.Get("engine", ""));
+    }
+
+    if (common_button_name == Common::Input::ButtonNames::Value) {
+        if (param.Has("hat")) {
+            const QString hat = QString::fromStdString(param.Get("direction", ""));
+            return QObject::tr("%1%2Hat %3").arg(toggle, inverted, hat);
+        }
+        if (param.Has("axis")) {
+            const QString axis = QString::fromStdString(param.Get("axis", ""));
+            return QObject::tr("%1%2Axis %3").arg(toggle, inverted, axis);
+        }
+        if (param.Has("axis_x") && param.Has("axis_y") && param.Has("axis_z")) {
+            const QString axis_x = QString::fromStdString(param.Get("axis_x", ""));
+            const QString axis_y = QString::fromStdString(param.Get("axis_y", ""));
+            const QString axis_z = QString::fromStdString(param.Get("axis_z", ""));
+            return QObject::tr("%1%2Axis %3,%4,%5").arg(toggle, inverted, axis_x, axis_y, axis_z);
+        }
+        if (param.Has("motion")) {
+            const QString motion = QString::fromStdString(param.Get("motion", ""));
+            return QObject::tr("%1%2Motion %3").arg(toggle, inverted, motion);
+        }
+        if (param.Has("button")) {
+            const QString button = QString::fromStdString(param.Get("button", ""));
+            return QObject::tr("%1%2Button %3").arg(toggle, inverted, button);
+        }
+    }
+
+    QString button_name = GetButtonName(common_button_name);
+    if (param.Has("hat")) {
+        return QObject::tr("%1%2Hat %3").arg(toggle, inverted, button_name);
+    }
+    if (param.Has("axis")) {
+        return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
+    }
+    if (param.Has("motion")) {
+        return QObject::tr("%1%2Axis %3").arg(toggle, inverted, button_name);
+    }
+    if (param.Has("button")) {
+        return QObject::tr("%1%2Button %3").arg(toggle, inverted, button_name);
+    }
+
+    return QObject::tr("[unknown]");
 }
 
 QString ConfigureInputPlayer::AnalogToText(const Common::ParamPackage& param,