Skip to content

Commit b6e4c76

Browse files
committed
input: export additional info for joysticks inputs
Added some extra info to help RetroPie's auto-configuration scripts: * export the joystick Vendor and Product IDs, which should help with RetroArch's joypad profile generation. * export device path (`/dev/input/eventXY`), which can help finding the system's (joystick/udev) name for the joystick (which can be retrived with a new 2.24.0 call). 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 alleviate these situations and new SDL versions in RetroPie. [1] RetroPie/RetroPie-Setup#3398
1 parent c11b9ec commit b6e4c76

3 files changed

Lines changed: 44 additions & 16 deletions

File tree

es-core/src/InputConfig.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "InputConfig.h"
22

33
#include "Log.h"
4+
#include "utils/StringUtil.h"
45
#include <pugixml/src/pugixml.hpp>
56

67
//some util functions
@@ -39,19 +40,11 @@ InputType stringToInputType(const std::string& type)
3940
}
4041

4142

42-
std::string toLower(std::string str)
43-
{
44-
for(unsigned int i = 0; i < str.length(); i++)
45-
{
46-
str[i] = (char)tolower(str[i]);
47-
}
48-
49-
return str;
50-
}
51-
//end util functions
52-
5343
InputConfig::InputConfig(int deviceId, const std::string& deviceName, const std::string& deviceGUID) : mDeviceId(deviceId), mDeviceName(deviceName), mDeviceGUID(deviceGUID)
5444
{
45+
mVendorId = 0;
46+
mProductId = 0;
47+
mDevicePath = "";
5548
}
5649

5750
void InputConfig::clear()
@@ -66,19 +59,19 @@ bool InputConfig::isConfigured()
6659

6760
void InputConfig::mapInput(const std::string& name, Input input)
6861
{
69-
mNameMap[toLower(name)] = input;
62+
mNameMap[Utils::String::toLower(name)] = input;
7063
}
7164

7265
void InputConfig::unmapInput(const std::string& name)
7366
{
74-
auto it = mNameMap.find(toLower(name));
67+
auto it = mNameMap.find(Utils::String::toLower(name));
7568
if(it != mNameMap.cend())
7669
mNameMap.erase(it);
7770
}
7871

7972
bool InputConfig::getInputByName(const std::string& name, Input* result)
8073
{
81-
auto it = mNameMap.find(toLower(name));
74+
auto it = mNameMap.find(Utils::String::toLower(name));
8275
if(it != mNameMap.cend())
8376
{
8477
*result = it->second;
@@ -188,7 +181,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node)
188181
if(value == 0)
189182
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
190183

191-
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
184+
mNameMap[Utils::String::toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
192185
}
193186
}
194187

@@ -210,6 +203,15 @@ void InputConfig::writeToXML(pugi::xml_node& parent)
210203
{
211204
cfg.append_attribute("type") = "joystick";
212205
cfg.append_attribute("deviceName") = mDeviceName.c_str();
206+
if(mVendorId && mProductId)
207+
{
208+
cfg.append_attribute("vendorId") = mVendorId;
209+
cfg.append_attribute("productId") = mProductId;
210+
}
211+
if(!mDevicePath.empty())
212+
{
213+
cfg.append_attribute("devicePath") = mDevicePath.c_str();
214+
}
213215
}
214216

215217
cfg.append_attribute("deviceGUID") = mDeviceGUID.c_str();

es-core/src/InputConfig.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,15 @@ class InputConfig
102102
void mapInput(const std::string& name, Input input);
103103
void unmapInput(const std::string& name); // unmap all Inputs mapped to this name
104104

105-
inline int getDeviceId() const { return mDeviceId; };
105+
inline int getDeviceId() const { return mDeviceId; }
106106
inline const std::string& getDeviceName() { return mDeviceName; }
107107
inline const std::string& getDeviceGUIDString() { return mDeviceGUID; }
108+
inline const unsigned short getVendorId() { return mVendorId; }
109+
inline const unsigned short getProductId() { return mProductId; }
110+
111+
inline void setVendorId(unsigned short vendorID) { mVendorId = vendorID; }
112+
inline void setProductId(unsigned short productID) { mProductId = productID; }
113+
inline void setDevicePath(const char *devPath) { if(devPath != NULL) mDevicePath = devPath; }
108114

109115
//Returns true if Input is mapped to this name, false otherwise.
110116
bool isMappedTo(const std::string& name, Input input);
@@ -127,6 +133,10 @@ class InputConfig
127133
const int mDeviceId;
128134
const std::string mDeviceName;
129135
const std::string mDeviceGUID;
136+
137+
unsigned short mVendorId;
138+
unsigned short mProductId;
139+
std::string mDevicePath;
130140
};
131141

132142
#endif // ES_CORE_INPUT_CONFIG_H

es-core/src/InputManager.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,22 @@ void InputManager::addJoystickByDeviceIndex(int id)
9999

100100
// create the InputConfig
101101
mInputConfigs[joyId] = new InputConfig(joyId, SDL_JoystickName(joy), guid);
102+
103+
// add Vendor and Product IDs
104+
mInputConfigs[joyId]->setVendorId(SDL_JoystickGetVendor(joy));
105+
mInputConfigs[joyId]->setProductId(SDL_JoystickGetProduct(joy));
106+
107+
// SDL version 2.24.0 adds the 'SDL_JoystickPathForIndex' function to get the (udev) device path
108+
#if SDL_VERSION_ATLEAST(2,24,0)
109+
SDL_version sdl_runtime;
110+
SDL_GetVersion(&sdl_runtime);
111+
if ((sdl_runtime.major >= 2) && (sdl_runtime.major > 2 || sdl_runtime.minor >= 24) && \
112+
(sdl_runtime.major > 2 || sdl_runtime.minor > 24 || sdl_runtime.patch >= 0))
113+
{
114+
mInputConfigs[joyId]->setDevicePath(SDL_JoystickPathForIndex(id));
115+
}
116+
#endif
117+
102118
if(!loadInputConfig(mInputConfigs[joyId]))
103119
{
104120
LOG(LogInfo) << "Added unconfigured joystick " << SDL_JoystickName(joy) << " (GUID: " << guid << ", instance ID: " << joyId << ", device index: " << id << ").";

0 commit comments

Comments
 (0)