Allow distinguishing PLIB joysticks by index (count)
This gives a simple way to have different config files for multiple identical devices, such as the Saitek/Logitech throttle-quadrant
This commit is contained in:
parent
0cdd6c4e70
commit
2ce4bcb666
4 changed files with 55 additions and 17 deletions
|
@ -49,14 +49,9 @@ FGDeviceConfigurationMap::FGDeviceConfigurationMap( const string& relative_path,
|
|||
{
|
||||
// scan for over-ride configurations, loaded via joysticks.xml, etc
|
||||
for (auto preloaded : nodePath->getChildren(nodeName)) {
|
||||
// allow specifying a serial number in the override
|
||||
std::string serial = preloaded->getStringValue("serial-number");
|
||||
if (!serial.empty()) {
|
||||
serial = "::" + serial;
|
||||
}
|
||||
|
||||
std::string suffix = computeSuffix(preloaded);
|
||||
for (auto nameProp : preloaded->getChildren("name")) {
|
||||
overrideDict[nameProp->getStringValue() + serial] = preloaded;
|
||||
overrideDict[nameProp->getStringValue() + suffix] = preloaded;
|
||||
} // of names iteration
|
||||
} // of defined overrides iteration
|
||||
|
||||
|
@ -64,6 +59,22 @@ FGDeviceConfigurationMap::FGDeviceConfigurationMap( const string& relative_path,
|
|||
scan_dir( SGPath(globals->get_fg_root(), relative_path));
|
||||
}
|
||||
|
||||
std::string FGDeviceConfigurationMap::computeSuffix(SGPropertyNode_ptr node)
|
||||
{
|
||||
if (node->hasChild("serial-number")) {
|
||||
return std::string("::") + node->getStringValue("serial-number");
|
||||
}
|
||||
|
||||
// allow specifying a device number / index in the override
|
||||
if (node->hasChild("device-number")) {
|
||||
std::ostringstream os;
|
||||
os << "_" << node->getIntValue("device-number");
|
||||
return os.str();
|
||||
}
|
||||
|
||||
return{};
|
||||
}
|
||||
|
||||
FGDeviceConfigurationMap::~FGDeviceConfigurationMap()
|
||||
{
|
||||
}
|
||||
|
@ -156,14 +167,10 @@ void FGDeviceConfigurationMap::refreshCacheForFile(const SGPath& path)
|
|||
return;
|
||||
}
|
||||
|
||||
std::string serial = n->getStringValue("serial-number");
|
||||
if (!serial.empty()) {
|
||||
serial = "::" + serial;
|
||||
}
|
||||
|
||||
std::string suffix = computeSuffix(n);
|
||||
string_list names;
|
||||
for (auto nameProp : n->getChildren("name")) {
|
||||
const string name = nameProp->getStringValue() + serial;
|
||||
const string name = nameProp->getStringValue() + suffix;
|
||||
names.push_back(name);
|
||||
// same comment as readCachedData: only insert if not already present
|
||||
if (namePathMap.find(name) == namePathMap.end()) {
|
||||
|
|
|
@ -54,6 +54,8 @@ private:
|
|||
void readCachedData(const SGPath& path);
|
||||
void refreshCacheForFile(const SGPath& path);
|
||||
|
||||
std::string computeSuffix(SGPropertyNode_ptr node);
|
||||
|
||||
typedef std::map<std::string, SGPropertyNode_ptr> NameNodeMap;
|
||||
// dictionary of over-ridden configurations, where the config data
|
||||
// was explicitly loaded and shoudl be picked over a file search
|
||||
|
|
|
@ -133,11 +133,16 @@ void FGJoystickInput::init()
|
|||
SG_LOG(SG_INPUT, SG_INFO, "Looking for bindings for joystick \"" << name << '"');
|
||||
SGPropertyNode_ptr named;
|
||||
|
||||
if (configMap.hasConfiguration(name)) {
|
||||
// allow distinguishing duplicated devices by the name
|
||||
string indexedName = computeDeviceIndexName(name, i);
|
||||
if (configMap.hasConfiguration(indexedName)) {
|
||||
named = configMap.configurationForDeviceName(indexedName);
|
||||
std::string source = named->getStringValue("source", "user defined");
|
||||
SG_LOG(SG_INPUT, SG_INFO, "... found joystick: " << source);
|
||||
} else if (configMap.hasConfiguration(name)) {
|
||||
named = configMap.configurationForDeviceName(name);
|
||||
std::string source = named->getStringValue("source", "user defined");
|
||||
SG_LOG(SG_INPUT, SG_INFO, "... found joystick: " << source);
|
||||
|
||||
} else if ((named = configMap.configurationForDeviceName("default"))) {
|
||||
std::string source = named->getStringValue("source", "user defined");
|
||||
SG_LOG(SG_INPUT, SG_INFO, "No config found for joystick \"" << name
|
||||
|
@ -154,6 +159,21 @@ void FGJoystickInput::init()
|
|||
}
|
||||
}
|
||||
|
||||
std::string FGJoystickInput::computeDeviceIndexName(const std::string& name,
|
||||
int lastIndex) const
|
||||
{
|
||||
int index = 0;
|
||||
for (int i = 0; i < lastIndex; i++) {
|
||||
if (joysticks[i].plibJS && (joysticks[i].plibJS->getName() == name)) {
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << name << "_" << index;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void FGJoystickInput::reinit() {
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "Re-Initializing joystick bindings");
|
||||
_remove(false);
|
||||
|
|
|
@ -50,7 +50,16 @@ public:
|
|||
static const int MAX_JOYSTICK_BUTTONS = 32;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief computeDeviceIndexName - compute the name including the index, based
|
||||
* on the number of identically named devices. This is used to allow multiple
|
||||
* different files for identical hardware, especially throttles
|
||||
* @param name - the base joystick name
|
||||
* @param lastIndex - don't check names at this index or above. Needed to
|
||||
* ensure we only check as far as the joystick we are currently processing
|
||||
* @return
|
||||
*/
|
||||
std::string computeDeviceIndexName(const std::string &name, int lastIndex) const;
|
||||
|
||||
void _remove(bool all);
|
||||
SGPropertyNode_ptr status_node;
|
||||
|
@ -91,7 +100,7 @@ private:
|
|||
|
||||
joystick joysticks[MAX_JOYSTICKS];
|
||||
void updateJoystick(int index, joystick* joy, double dt);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue