Added an option to the Input device settings menu to swap the A/B and X/Y buttons

This commit is contained in:
Leon Styhre 2024-01-17 22:09:50 +01:00
parent 9d824af40a
commit dcb2aaedef
5 changed files with 134 additions and 96 deletions

View file

@ -127,7 +127,7 @@ std::string UIModeController::getFormattedPassKeyStr()
std::string symbolX; std::string symbolX;
std::string symbolY; std::string symbolY;
if (controllerType == "snes") { if (Settings::getInstance()->getBool("InputSwapButtons") || controllerType == "snes") {
symbolA = "B"; symbolA = "B";
symbolB = "A"; symbolB = "A";
symbolX = "Y"; symbolX = "Y";

View file

@ -1293,6 +1293,17 @@ void GuiMenu::openInputDeviceOptions()
} }
}); });
// Whether to swap the A/B and X/Y buttons.
auto inputSwapButtons = std::make_shared<SwitchComponent>();
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. // Configure keyboard and controllers.
ComponentListRow configureInputRow; ComponentListRow configureInputRow;
configureInputRow.elements.clear(); configureInputRow.elements.clear();

View file

@ -9,6 +9,7 @@
#include "InputConfig.h" #include "InputConfig.h"
#include "Log.h" #include "Log.h"
#include "Settings.h"
#include <pugixml.hpp> #include <pugixml.hpp>
@ -54,7 +55,7 @@ InputType InputConfig::stringToInputType(const std::string& type)
std::string InputConfig::toLower(std::string str) 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<char>(tolower(str[i])); str[i] = static_cast<char>(tolower(str[i]));
return str; return str;
@ -125,7 +126,7 @@ std::vector<std::string> InputConfig::getMappedTo(Input input)
std::vector<std::string> maps; std::vector<std::string> maps;
for (auto it = mNameMap.cbegin(); it != mNameMap.cend(); ++it) { for (auto it = mNameMap.cbegin(); it != mNameMap.cend(); ++it) {
Input chk = it->second; Input chk {it->second};
if (!chk.configured) if (!chk.configured)
continue; continue;
@ -145,7 +146,20 @@ std::vector<std::string> InputConfig::getMappedTo(Input input)
bool InputConfig::getInputByName(const std::string& name, Input* result) 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()) { if (it != mNameMap.cend()) {
*result = it->second; *result = it->second;
return true; return true;
@ -166,10 +180,10 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
{ {
clear(); clear();
for (pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) { for (pugi::xml_node input {node.child("input")}; input; input = input.next_sibling("input")) {
std::string name = input.attribute("name").as_string(); std::string name {input.attribute("name").as_string()};
std::string type = input.attribute("type").as_string(); std::string type {input.attribute("type").as_string()};
InputType typeEnum = stringToInputType(type); InputType typeEnum {stringToInputType(type)};
if (typeEnum == TYPE_COUNT) { if (typeEnum == TYPE_COUNT) {
LOG(LogError) << "InputConfig load error - input of type \"" << type LOG(LogError) << "InputConfig load error - input of type \"" << type
@ -177,8 +191,8 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
continue; continue;
} }
int id = input.attribute("id").as_int(); int id {input.attribute("id").as_int()};
int value = input.attribute("value").as_int(); int value {input.attribute("value").as_int()};
if (value == 0) { if (value == 0) {
LOG(LogWarning) << "InputConfig value is 0 for " << type << " " << id << "!\n"; 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) 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) { if (mDeviceId == DEVICE_KEYBOARD) {
cfg.append_attribute("type") = "keyboard"; cfg.append_attribute("type") = "keyboard";
@ -211,7 +225,7 @@ void InputConfig::writeToXML(pugi::xml_node& parent)
if (!it->second.configured) if (!it->second.configured)
continue; 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("name") = it->first.c_str();
input.append_attribute("type") = inputTypeToString(it->second.type).c_str(); input.append_attribute("type") = inputTypeToString(it->second.type).c_str();
input.append_attribute("id").set_value(it->second.id); input.append_attribute("id").set_value(it->second.id);

View file

@ -246,6 +246,7 @@ void Settings::setDefaults()
#endif #endif
mBoolMap["InputOnlyFirstController"] = {false, false}; mBoolMap["InputOnlyFirstController"] = {false, false};
mBoolMap["InputIgnoreKeyboard"] = {false, false}; mBoolMap["InputIgnoreKeyboard"] = {false, false};
mBoolMap["InputSwapButtons"] = {false, false};
// Game collection settings. // Game collection settings.
mStringMap["CollectionSystemsAuto"] = {"", ""}; mStringMap["CollectionSystemsAuto"] = {"", ""};

View file

@ -33,6 +33,18 @@ void HelpComponent::assignIcons()
std::map<std::string, std::string> sIconPathMapOld {sIconPathMap}; std::map<std::string, std::string> sIconPathMapOld {sIconPathMap};
sIconPathMap.clear(); 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. // These graphics files are common between all controller types.
sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ? sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ?
":/graphics/help/dpad_updown.svg" : ":/graphics/help/dpad_updown.svg" :
@ -67,16 +79,16 @@ void HelpComponent::assignIcons()
// These graphics files are custom per controller type. // These graphics files are custom per controller type.
if (controllerType == "snes") { if (controllerType == "snes") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_SNES.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_SNES.empty() ?
":/graphics/help/button_a_SNES.svg" : ":/graphics/help/button_a_SNES.svg" :
mStyle.mCustomButtons.button_a_SNES; mStyle.mCustomButtons.button_a_SNES;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_SNES.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_SNES.empty() ?
":/graphics/help/button_b_SNES.svg" : ":/graphics/help/button_b_SNES.svg" :
mStyle.mCustomButtons.button_b_SNES; mStyle.mCustomButtons.button_b_SNES;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_SNES.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_SNES.empty() ?
":/graphics/help/button_x_SNES.svg" : ":/graphics/help/button_x_SNES.svg" :
mStyle.mCustomButtons.button_x_SNES; mStyle.mCustomButtons.button_x_SNES;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_SNES.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_SNES.empty() ?
":/graphics/help/button_y_SNES.svg" : ":/graphics/help/button_y_SNES.svg" :
mStyle.mCustomButtons.button_y_SNES; mStyle.mCustomButtons.button_y_SNES;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_SNES.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_SNES.empty() ?
@ -87,16 +99,16 @@ void HelpComponent::assignIcons()
mStyle.mCustomButtons.button_start_SNES; mStyle.mCustomButtons.button_start_SNES;
} }
else if (controllerType == "switchpro") { else if (controllerType == "switchpro") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_switch.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_switch.empty() ?
":/graphics/help/button_a_switch.svg" : ":/graphics/help/button_a_switch.svg" :
mStyle.mCustomButtons.button_a_switch; mStyle.mCustomButtons.button_a_switch;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_switch.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_switch.empty() ?
":/graphics/help/button_b_switch.svg" : ":/graphics/help/button_b_switch.svg" :
mStyle.mCustomButtons.button_b_switch; mStyle.mCustomButtons.button_b_switch;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_switch.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_switch.empty() ?
":/graphics/help/button_x_switch.svg" : ":/graphics/help/button_x_switch.svg" :
mStyle.mCustomButtons.button_x_switch; mStyle.mCustomButtons.button_x_switch;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_switch.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_switch.empty() ?
":/graphics/help/button_y_switch.svg" : ":/graphics/help/button_y_switch.svg" :
mStyle.mCustomButtons.button_y_switch; mStyle.mCustomButtons.button_y_switch;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_switch.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_switch.empty() ?
@ -107,16 +119,16 @@ void HelpComponent::assignIcons()
mStyle.mCustomButtons.button_start_switch; mStyle.mCustomButtons.button_start_switch;
} }
else if (controllerType == "ps123") { else if (controllerType == "ps123") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ?
":/graphics/help/button_a_PS.svg" : ":/graphics/help/button_a_PS.svg" :
mStyle.mCustomButtons.button_a_PS; mStyle.mCustomButtons.button_a_PS;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ?
":/graphics/help/button_b_PS.svg" : ":/graphics/help/button_b_PS.svg" :
mStyle.mCustomButtons.button_b_PS; mStyle.mCustomButtons.button_b_PS;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ?
":/graphics/help/button_x_PS.svg" : ":/graphics/help/button_x_PS.svg" :
mStyle.mCustomButtons.button_x_PS; mStyle.mCustomButtons.button_x_PS;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ?
":/graphics/help/button_y_PS.svg" : ":/graphics/help/button_y_PS.svg" :
mStyle.mCustomButtons.button_y_PS; mStyle.mCustomButtons.button_y_PS;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS123.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS123.empty() ?
@ -127,16 +139,16 @@ void HelpComponent::assignIcons()
mStyle.mCustomButtons.button_start_PS123; mStyle.mCustomButtons.button_start_PS123;
} }
else if (controllerType == "ps4") { else if (controllerType == "ps4") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ?
":/graphics/help/button_a_PS.svg" : ":/graphics/help/button_a_PS.svg" :
mStyle.mCustomButtons.button_a_PS; mStyle.mCustomButtons.button_a_PS;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ?
":/graphics/help/button_b_PS.svg" : ":/graphics/help/button_b_PS.svg" :
mStyle.mCustomButtons.button_b_PS; mStyle.mCustomButtons.button_b_PS;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ?
":/graphics/help/button_x_PS.svg" : ":/graphics/help/button_x_PS.svg" :
mStyle.mCustomButtons.button_x_PS; mStyle.mCustomButtons.button_x_PS;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ?
":/graphics/help/button_y_PS.svg" : ":/graphics/help/button_y_PS.svg" :
mStyle.mCustomButtons.button_y_PS; mStyle.mCustomButtons.button_y_PS;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS4.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS4.empty() ?
@ -147,16 +159,16 @@ void HelpComponent::assignIcons()
mStyle.mCustomButtons.button_start_PS4; mStyle.mCustomButtons.button_start_PS4;
} }
else if (controllerType == "ps5") { else if (controllerType == "ps5") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ?
":/graphics/help/button_a_PS.svg" : ":/graphics/help/button_a_PS.svg" :
mStyle.mCustomButtons.button_a_PS; mStyle.mCustomButtons.button_a_PS;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ?
":/graphics/help/button_b_PS.svg" : ":/graphics/help/button_b_PS.svg" :
mStyle.mCustomButtons.button_b_PS; mStyle.mCustomButtons.button_b_PS;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ?
":/graphics/help/button_x_PS.svg" : ":/graphics/help/button_x_PS.svg" :
mStyle.mCustomButtons.button_x_PS; mStyle.mCustomButtons.button_x_PS;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ?
":/graphics/help/button_y_PS.svg" : ":/graphics/help/button_y_PS.svg" :
mStyle.mCustomButtons.button_y_PS; mStyle.mCustomButtons.button_y_PS;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS5.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS5.empty() ?
@ -168,16 +180,16 @@ void HelpComponent::assignIcons()
} }
else if (controllerType == "xbox360") { else if (controllerType == "xbox360") {
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ?
":/graphics/help/button_a_XBOX.svg" : ":/graphics/help/button_a_XBOX.svg" :
mStyle.mCustomButtons.button_a_XBOX; mStyle.mCustomButtons.button_a_XBOX;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ?
":/graphics/help/button_b_XBOX.svg" : ":/graphics/help/button_b_XBOX.svg" :
mStyle.mCustomButtons.button_b_XBOX; mStyle.mCustomButtons.button_b_XBOX;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ?
":/graphics/help/button_x_XBOX.svg" : ":/graphics/help/button_x_XBOX.svg" :
mStyle.mCustomButtons.button_x_XBOX; mStyle.mCustomButtons.button_x_XBOX;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ?
":/graphics/help/button_y_XBOX.svg" : ":/graphics/help/button_y_XBOX.svg" :
mStyle.mCustomButtons.button_y_XBOX; mStyle.mCustomButtons.button_y_XBOX;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX360.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX360.empty() ?
@ -189,16 +201,16 @@ void HelpComponent::assignIcons()
} }
else { else {
// Xbox One and later. // Xbox One and later.
sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ?
":/graphics/help/button_a_XBOX.svg" : ":/graphics/help/button_a_XBOX.svg" :
mStyle.mCustomButtons.button_a_XBOX; mStyle.mCustomButtons.button_a_XBOX;
sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ?
":/graphics/help/button_b_XBOX.svg" : ":/graphics/help/button_b_XBOX.svg" :
mStyle.mCustomButtons.button_b_XBOX; mStyle.mCustomButtons.button_b_XBOX;
sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ?
":/graphics/help/button_x_XBOX.svg" : ":/graphics/help/button_x_XBOX.svg" :
mStyle.mCustomButtons.button_x_XBOX; mStyle.mCustomButtons.button_x_XBOX;
sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ?
":/graphics/help/button_y_XBOX.svg" : ":/graphics/help/button_y_XBOX.svg" :
mStyle.mCustomButtons.button_y_XBOX; mStyle.mCustomButtons.button_y_XBOX;
sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX.empty() ? sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX.empty() ?