From dcb2aaedef8c0b9694c1b0dccf4c72939d3fd813 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Wed, 17 Jan 2024 22:09:50 +0100 Subject: [PATCH] Added an option to the Input device settings menu to swap the A/B and X/Y buttons --- es-app/src/UIModeController.cpp | 2 +- es-app/src/guis/GuiMenu.cpp | 11 ++ es-core/src/InputConfig.cpp | 36 +++-- es-core/src/Settings.cpp | 1 + es-core/src/components/HelpComponent.cpp | 180 ++++++++++++----------- 5 files changed, 134 insertions(+), 96 deletions(-) diff --git a/es-app/src/UIModeController.cpp b/es-app/src/UIModeController.cpp index d7e62fa74..aa7fd2d02 100644 --- a/es-app/src/UIModeController.cpp +++ b/es-app/src/UIModeController.cpp @@ -127,7 +127,7 @@ std::string UIModeController::getFormattedPassKeyStr() std::string symbolX; std::string symbolY; - if (controllerType == "snes") { + if (Settings::getInstance()->getBool("InputSwapButtons") || controllerType == "snes") { symbolA = "B"; symbolB = "A"; symbolX = "Y"; diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 12e816884..058f47d27 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -1293,6 +1293,17 @@ void GuiMenu::openInputDeviceOptions() } }); + // Whether to swap the A/B and X/Y buttons. + auto inputSwapButtons = std::make_shared(); + inputSwapButtons->setState(Settings::getInstance()->getBool("InputSwapButtons")); + s->addWithLabel("SWAP A/B AND X/Y BUTTONS", inputSwapButtons); + s->addSaveFunc([inputSwapButtons, s] { + if (Settings::getInstance()->getBool("InputSwapButtons") != inputSwapButtons->getState()) { + Settings::getInstance()->setBool("InputSwapButtons", inputSwapButtons->getState()); + s->setNeedsSaving(); + } + }); + // Configure keyboard and controllers. ComponentListRow configureInputRow; configureInputRow.elements.clear(); diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index 8f9e30ca8..e8d334183 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -9,6 +9,7 @@ #include "InputConfig.h" #include "Log.h" +#include "Settings.h" #include @@ -54,7 +55,7 @@ InputType InputConfig::stringToInputType(const std::string& type) std::string InputConfig::toLower(std::string str) { - for (unsigned int i = 0; i < str.length(); ++i) + for (unsigned int i {0}; i < str.length(); ++i) str[i] = static_cast(tolower(str[i])); return str; @@ -125,7 +126,7 @@ std::vector InputConfig::getMappedTo(Input input) std::vector maps; for (auto it = mNameMap.cbegin(); it != mNameMap.cend(); ++it) { - Input chk = it->second; + Input chk {it->second}; if (!chk.configured) continue; @@ -145,7 +146,20 @@ std::vector InputConfig::getMappedTo(Input input) bool InputConfig::getInputByName(const std::string& name, Input* result) { - auto it = mNameMap.find(toLower(name)); + std::string nameInput {name}; + + if (Settings::getInstance()->getBool("InputSwapButtons")) { + if (name == "a") + nameInput = "b"; + else if (name == "b") + nameInput = "a"; + else if (name == "x") + nameInput = "y"; + else if (name == "y") + nameInput = "x"; + } + + auto it = mNameMap.find(toLower(nameInput)); if (it != mNameMap.cend()) { *result = it->second; return true; @@ -166,10 +180,10 @@ void InputConfig::loadFromXML(pugi::xml_node& node) { clear(); - for (pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) { - std::string name = input.attribute("name").as_string(); - std::string type = input.attribute("type").as_string(); - InputType typeEnum = stringToInputType(type); + for (pugi::xml_node input {node.child("input")}; input; input = input.next_sibling("input")) { + std::string name {input.attribute("name").as_string()}; + std::string type {input.attribute("type").as_string()}; + InputType typeEnum {stringToInputType(type)}; if (typeEnum == TYPE_COUNT) { LOG(LogError) << "InputConfig load error - input of type \"" << type @@ -177,8 +191,8 @@ void InputConfig::loadFromXML(pugi::xml_node& node) continue; } - int id = input.attribute("id").as_int(); - int value = input.attribute("value").as_int(); + int id {input.attribute("id").as_int()}; + int value {input.attribute("value").as_int()}; if (value == 0) { LOG(LogWarning) << "InputConfig value is 0 for " << type << " " << id << "!\n"; @@ -190,7 +204,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node) void InputConfig::writeToXML(pugi::xml_node& parent) { - pugi::xml_node cfg = parent.append_child("inputConfig"); + pugi::xml_node cfg {parent.append_child("inputConfig")}; if (mDeviceId == DEVICE_KEYBOARD) { cfg.append_attribute("type") = "keyboard"; @@ -211,7 +225,7 @@ void InputConfig::writeToXML(pugi::xml_node& parent) if (!it->second.configured) continue; - pugi::xml_node input = cfg.append_child("input"); + pugi::xml_node input {cfg.append_child("input")}; input.append_attribute("name") = it->first.c_str(); input.append_attribute("type") = inputTypeToString(it->second.type).c_str(); input.append_attribute("id").set_value(it->second.id); diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 02f3f11e1..a6722faae 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -246,6 +246,7 @@ void Settings::setDefaults() #endif mBoolMap["InputOnlyFirstController"] = {false, false}; mBoolMap["InputIgnoreKeyboard"] = {false, false}; + mBoolMap["InputSwapButtons"] = {false, false}; // Game collection settings. mStringMap["CollectionSystemsAuto"] = {"", ""}; diff --git a/es-core/src/components/HelpComponent.cpp b/es-core/src/components/HelpComponent.cpp index 3bb36c882..fd42b8d65 100644 --- a/es-core/src/components/HelpComponent.cpp +++ b/es-core/src/components/HelpComponent.cpp @@ -33,6 +33,18 @@ void HelpComponent::assignIcons() std::map sIconPathMapOld {sIconPathMap}; sIconPathMap.clear(); + std::string buttonA {"a"}; + std::string buttonB {"b"}; + std::string buttonX {"x"}; + std::string buttonY {"y"}; + + if (Settings::getInstance()->getBool("InputSwapButtons")) { + buttonA = "b"; + buttonB = "a"; + buttonX = "y"; + buttonY = "x"; + } + // These graphics files are common between all controller types. sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ? ":/graphics/help/dpad_updown.svg" : @@ -67,18 +79,18 @@ void HelpComponent::assignIcons() // These graphics files are custom per controller type. if (controllerType == "snes") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_SNES.empty() ? - ":/graphics/help/button_a_SNES.svg" : - mStyle.mCustomButtons.button_a_SNES; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_SNES.empty() ? - ":/graphics/help/button_b_SNES.svg" : - mStyle.mCustomButtons.button_b_SNES; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_SNES.empty() ? - ":/graphics/help/button_x_SNES.svg" : - mStyle.mCustomButtons.button_x_SNES; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_SNES.empty() ? - ":/graphics/help/button_y_SNES.svg" : - mStyle.mCustomButtons.button_y_SNES; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_SNES.empty() ? + ":/graphics/help/button_a_SNES.svg" : + mStyle.mCustomButtons.button_a_SNES; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_SNES.empty() ? + ":/graphics/help/button_b_SNES.svg" : + mStyle.mCustomButtons.button_b_SNES; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_SNES.empty() ? + ":/graphics/help/button_x_SNES.svg" : + mStyle.mCustomButtons.button_x_SNES; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_SNES.empty() ? + ":/graphics/help/button_y_SNES.svg" : + mStyle.mCustomButtons.button_y_SNES; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_SNES.empty() ? ":/graphics/help/button_back_SNES.svg" : mStyle.mCustomButtons.button_back_SNES; @@ -87,18 +99,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_SNES; } else if (controllerType == "switchpro") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_switch.empty() ? - ":/graphics/help/button_a_switch.svg" : - mStyle.mCustomButtons.button_a_switch; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_switch.empty() ? - ":/graphics/help/button_b_switch.svg" : - mStyle.mCustomButtons.button_b_switch; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_switch.empty() ? - ":/graphics/help/button_x_switch.svg" : - mStyle.mCustomButtons.button_x_switch; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_switch.empty() ? - ":/graphics/help/button_y_switch.svg" : - mStyle.mCustomButtons.button_y_switch; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_switch.empty() ? + ":/graphics/help/button_a_switch.svg" : + mStyle.mCustomButtons.button_a_switch; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_switch.empty() ? + ":/graphics/help/button_b_switch.svg" : + mStyle.mCustomButtons.button_b_switch; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_switch.empty() ? + ":/graphics/help/button_x_switch.svg" : + mStyle.mCustomButtons.button_x_switch; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_switch.empty() ? + ":/graphics/help/button_y_switch.svg" : + mStyle.mCustomButtons.button_y_switch; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_switch.empty() ? ":/graphics/help/button_back_switch.svg" : mStyle.mCustomButtons.button_back_switch; @@ -107,18 +119,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_switch; } else if (controllerType == "ps123") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS123.empty() ? ":/graphics/help/button_back_PS123.svg" : mStyle.mCustomButtons.button_back_PS123; @@ -127,18 +139,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_PS123; } else if (controllerType == "ps4") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS4.empty() ? ":/graphics/help/button_back_PS4.svg" : mStyle.mCustomButtons.button_back_PS4; @@ -147,18 +159,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_PS4; } else if (controllerType == "ps5") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS5.empty() ? ":/graphics/help/button_back_PS5.svg" : mStyle.mCustomButtons.button_back_PS5; @@ -168,18 +180,18 @@ void HelpComponent::assignIcons() } else if (controllerType == "xbox360") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? - ":/graphics/help/button_a_XBOX.svg" : - mStyle.mCustomButtons.button_a_XBOX; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? - ":/graphics/help/button_b_XBOX.svg" : - mStyle.mCustomButtons.button_b_XBOX; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? - ":/graphics/help/button_x_XBOX.svg" : - mStyle.mCustomButtons.button_x_XBOX; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? - ":/graphics/help/button_y_XBOX.svg" : - mStyle.mCustomButtons.button_y_XBOX; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ? + ":/graphics/help/button_a_XBOX.svg" : + mStyle.mCustomButtons.button_a_XBOX; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ? + ":/graphics/help/button_b_XBOX.svg" : + mStyle.mCustomButtons.button_b_XBOX; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ? + ":/graphics/help/button_x_XBOX.svg" : + mStyle.mCustomButtons.button_x_XBOX; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ? + ":/graphics/help/button_y_XBOX.svg" : + mStyle.mCustomButtons.button_y_XBOX; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX360.empty() ? ":/graphics/help/button_back_XBOX360.svg" : mStyle.mCustomButtons.button_back_XBOX360; @@ -189,18 +201,18 @@ void HelpComponent::assignIcons() } else { // Xbox One and later. - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? - ":/graphics/help/button_a_XBOX.svg" : - mStyle.mCustomButtons.button_a_XBOX; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? - ":/graphics/help/button_b_XBOX.svg" : - mStyle.mCustomButtons.button_b_XBOX; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? - ":/graphics/help/button_x_XBOX.svg" : - mStyle.mCustomButtons.button_x_XBOX; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? - ":/graphics/help/button_y_XBOX.svg" : - mStyle.mCustomButtons.button_y_XBOX; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ? + ":/graphics/help/button_a_XBOX.svg" : + mStyle.mCustomButtons.button_a_XBOX; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ? + ":/graphics/help/button_b_XBOX.svg" : + mStyle.mCustomButtons.button_b_XBOX; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ? + ":/graphics/help/button_x_XBOX.svg" : + mStyle.mCustomButtons.button_x_XBOX; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ? + ":/graphics/help/button_y_XBOX.svg" : + mStyle.mCustomButtons.button_y_XBOX; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX.empty() ? ":/graphics/help/button_back_XBOX.svg" : mStyle.mCustomButtons.button_back_XBOX;