From b01984a16101fea587aabeeb207e93ebdc37cc19 Mon Sep 17 00:00:00 2001 From: cmitu <31816814+cmitu@users.noreply.github.com> Date: Thu, 23 Jun 2022 04:43:35 +0100 Subject: [PATCH] input: export additional info for joysticks inputs Added some extra info to help RetroPie's auto-configuration scripts by exporting the joystick Vendor and Product IDs, which should help with RetroArch's joypad profile generation. Since 2.0.14, SDL's joystick name (`SDL_CreateJoystickName`) is a normalized version of the name reported by the OS (culled consecutive spaces, trimming trailing spaces, renaming known joystick names like Xbox/PS). This breaks the input auto-configuration scripts in RetroPie, which generate a config with new name, while the emulators/ports expect to find the OS reported name (e.g. RetroArch - see #3398 [1] for an example). This issue is affecting especially PC users, which are not using RetroPie's (old) SDL version and who's RetroArch configuration is incomplete. Using the Vendor/Product ID would help these situations and support the new SDL versions when added to RetroPie. [1] https://github.com/RetroPie/RetroPie-Setup/issues/3398 --- es-core/src/InputConfig.cpp | 27 ++++++++++++--------------- es-core/src/InputConfig.h | 10 +++++++++- es-core/src/InputManager.cpp | 5 +++++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index eb5e59cecd..3a85ebbe08 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -1,6 +1,7 @@ #include "InputConfig.h" #include "Log.h" +#include "utils/StringUtil.h" #include //some util functions @@ -39,19 +40,10 @@ InputType stringToInputType(const std::string& type) } -std::string toLower(std::string str) -{ - for(unsigned int i = 0; i < str.length(); i++) - { - str[i] = (char)tolower(str[i]); - } - - return str; -} -//end util functions - InputConfig::InputConfig(int deviceId, const std::string& deviceName, const std::string& deviceGUID) : mDeviceId(deviceId), mDeviceName(deviceName), mDeviceGUID(deviceGUID) { + mVendorId = 0; + mProductId = 0; } void InputConfig::clear() @@ -66,19 +58,19 @@ bool InputConfig::isConfigured() void InputConfig::mapInput(const std::string& name, Input input) { - mNameMap[toLower(name)] = input; + mNameMap[Utils::String::toLower(name)] = input; } void InputConfig::unmapInput(const std::string& name) { - auto it = mNameMap.find(toLower(name)); + auto it = mNameMap.find(Utils::String::toLower(name)); if(it != mNameMap.cend()) mNameMap.erase(it); } bool InputConfig::getInputByName(const std::string& name, Input* result) { - auto it = mNameMap.find(toLower(name)); + auto it = mNameMap.find(Utils::String::toLower(name)); if(it != mNameMap.cend()) { *result = it->second; @@ -188,7 +180,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node) if(value == 0) LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n"; - mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); + mNameMap[Utils::String::toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); } } @@ -210,6 +202,11 @@ void InputConfig::writeToXML(pugi::xml_node& parent) { cfg.append_attribute("type") = "joystick"; cfg.append_attribute("deviceName") = mDeviceName.c_str(); + if(mVendorId && mProductId) + { + cfg.append_attribute("vendorId") = mVendorId; + cfg.append_attribute("productId") = mProductId; + } } cfg.append_attribute("deviceGUID") = mDeviceGUID.c_str(); diff --git a/es-core/src/InputConfig.h b/es-core/src/InputConfig.h index 4969d8ff02..a038e270fc 100644 --- a/es-core/src/InputConfig.h +++ b/es-core/src/InputConfig.h @@ -102,9 +102,14 @@ class InputConfig void mapInput(const std::string& name, Input input); void unmapInput(const std::string& name); // unmap all Inputs mapped to this name - inline int getDeviceId() const { return mDeviceId; }; + inline int getDeviceId() const { return mDeviceId; } inline const std::string& getDeviceName() { return mDeviceName; } inline const std::string& getDeviceGUIDString() { return mDeviceGUID; } + inline const unsigned short getVendorId() { return mVendorId; } + inline const unsigned short getProductId() { return mProductId; } + + inline void setVendorId(unsigned short vendorID) { mVendorId = vendorID; } + inline void setProductId(unsigned short productID) { mProductId = productID; } //Returns true if Input is mapped to this name, false otherwise. bool isMappedTo(const std::string& name, Input input); @@ -127,6 +132,9 @@ class InputConfig const int mDeviceId; const std::string mDeviceName; const std::string mDeviceGUID; + + unsigned short mVendorId; + unsigned short mProductId; }; #endif // ES_CORE_INPUT_CONFIG_H diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 46e5fdf60a..94e18ef96d 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -100,6 +100,11 @@ void InputManager::addJoystickByDeviceIndex(int id) // create the InputConfig mInputConfigs[joyId] = new InputConfig(joyId, SDL_JoystickName(joy), guid); + + // add Vendor and Product IDs + mInputConfigs[joyId]->setVendorId(SDL_JoystickGetVendor(joy)); + mInputConfigs[joyId]->setProductId(SDL_JoystickGetProduct(joy)); + if(!loadInputConfig(mInputConfigs[joyId])) { LOG(LogInfo) << "Added unconfigured joystick '" << SDL_JoystickName(joy) << "' (GUID: " << guid << ", instance ID: " << joyId << ", device index: " << id << ").";