ES-DE/es-core/src/InputConfig.cpp

234 lines
5.6 KiB
C++
Raw Normal View History

2013-04-08 14:27:38 +00:00
#include "InputConfig.h"
2017-11-01 22:21:10 +00:00
#include "Log.h"
2017-11-10 19:16:42 +00:00
#include <pugixml/src/pugixml.hpp>
2013-04-08 14:27:38 +00:00
2013-04-11 22:27:27 +00:00
//some util functions
std::string inputTypeToString(InputType type)
{
switch(type)
{
case TYPE_AXIS:
return "axis";
case TYPE_BUTTON:
return "button";
case TYPE_HAT:
return "hat";
case TYPE_KEY:
return "key";
2017-11-08 22:22:15 +00:00
case TYPE_CEC_BUTTON:
return "cec-button";
2013-04-11 22:27:27 +00:00
default:
return "error";
}
}
InputType stringToInputType(const std::string& type)
{
if(type == "axis")
return TYPE_AXIS;
if(type == "button")
return TYPE_BUTTON;
if(type == "hat")
return TYPE_HAT;
if(type == "key")
return TYPE_KEY;
2017-11-08 22:22:15 +00:00
if(type == "cec-button")
return TYPE_CEC_BUTTON;
2013-04-11 22:27:27 +00:00
return TYPE_COUNT;
}
2013-04-08 14:27:38 +00:00
std::string toLower(std::string str)
{
for(unsigned int i = 0; i < str.length(); i++)
{
2017-11-17 14:58:52 +00:00
str[i] = (char)tolower(str[i]);
2013-04-08 14:27:38 +00:00
}
return str;
}
2013-04-11 22:27:27 +00:00
//end util functions
2013-04-08 14:27:38 +00:00
InputConfig::InputConfig(int deviceId, const std::string& deviceName, const std::string& deviceGUID) : mDeviceId(deviceId), mDeviceName(deviceName), mDeviceGUID(deviceGUID)
2013-04-08 14:27:38 +00:00
{
}
void InputConfig::clear()
{
mNameMap.clear();
}
bool InputConfig::isConfigured()
{
return mNameMap.size() > 0;
}
2013-04-08 14:27:38 +00:00
void InputConfig::mapInput(const std::string& name, Input input)
{
mNameMap[toLower(name)] = input;
}
void InputConfig::unmapInput(const std::string& name)
{
auto it = mNameMap.find(toLower(name));
2017-11-11 14:56:22 +00:00
if(it != mNameMap.cend())
mNameMap.erase(it);
}
bool InputConfig::getInputByName(const std::string& name, Input* result)
2013-04-08 14:27:38 +00:00
{
auto it = mNameMap.find(toLower(name));
2017-11-11 14:56:22 +00:00
if(it != mNameMap.cend())
{
*result = it->second;
return true;
}
return false;
2013-04-08 14:27:38 +00:00
}
bool InputConfig::isMappedTo(const std::string& name, Input input)
{
Input comp;
if(!getInputByName(name, &comp))
return false;
2013-04-08 14:27:38 +00:00
if(comp.configured && comp.type == input.type && comp.id == input.id)
{
if(comp.type == TYPE_HAT)
{
return (input.value == 0 || input.value & comp.value);
}
if(comp.type == TYPE_AXIS)
{
return input.value == 0 || comp.value == input.value;
}else{
return true;
}
}
return false;
}
2018-11-15 16:38:20 +00:00
bool InputConfig::isMappedLike(const std::string& name, Input input)
{
if(name == "left")
{
return isMappedTo("left", input) || isMappedTo("leftanalogleft", input) || isMappedTo("rightanalogleft", input);
}else if(name == "right"){
return isMappedTo("right", input) || isMappedTo("leftanalogright", input) || isMappedTo("rightanalogright", input);
}else if(name == "up"){
return isMappedTo("up", input) || isMappedTo("leftanalogup", input) || isMappedTo("rightanalogup", input);
}else if(name == "down"){
return isMappedTo("down", input) || isMappedTo("leftanalogdown", input) || isMappedTo("rightanalogdown", input);
}else if(name == "leftshoulder"){
return isMappedTo("leftshoulder", input) || isMappedTo("pageup", input);
}else if(name == "rightshoulder"){
return isMappedTo("rightshoulder", input) || isMappedTo("pagedown", input);
}else if(name == "lefttrigger"){
return isMappedTo("lefttrigger", input) || isMappedTo("home", input);
}else if(name == "righttrigger"){
return isMappedTo("righttrigger", input) || isMappedTo("end", input);
2018-11-15 16:38:20 +00:00
}
return isMappedTo(name, input);
}
2013-04-08 14:27:38 +00:00
std::vector<std::string> InputConfig::getMappedTo(Input input)
{
std::vector<std::string> maps;
2017-11-11 14:56:22 +00:00
typedef std::map<std::string, Input>::const_iterator it_type;
for(it_type iterator = mNameMap.cbegin(); iterator != mNameMap.cend(); iterator++)
2013-04-08 14:27:38 +00:00
{
Input chk = iterator->second;
if(!chk.configured)
continue;
if(chk.device == input.device && chk.type == input.type && chk.id == input.id)
{
if(chk.type == TYPE_HAT)
{
if(input.value == 0 || input.value & chk.value)
{
maps.push_back(iterator->first);
}
continue;
}
if(input.type == TYPE_AXIS)
{
if(input.value == 0 || chk.value == input.value)
maps.push_back(iterator->first);
}else{
maps.push_back(iterator->first);
}
}
}
return maps;
}
2017-11-10 19:16:42 +00:00
void InputConfig::loadFromXML(pugi::xml_node& node)
2013-04-11 22:27:27 +00:00
{
clear();
2013-04-11 22:27:27 +00:00
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 << "\" is invalid! Skipping input \"" << name << "\".\n";
2013-04-11 22:27:27 +00:00
continue;
}
int id = input.attribute("id").as_int();
int value = input.attribute("value").as_int();
if(value == 0)
LOG(LogWarning) << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n";
2013-04-11 22:27:27 +00:00
mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true);
}
}
2017-11-10 19:16:42 +00:00
void InputConfig::writeToXML(pugi::xml_node& parent)
2013-04-11 22:27:27 +00:00
{
pugi::xml_node cfg = parent.append_child("inputConfig");
if(mDeviceId == DEVICE_KEYBOARD)
{
2013-04-11 22:27:27 +00:00
cfg.append_attribute("type") = "keyboard";
cfg.append_attribute("deviceName") = "Keyboard";
}
else if(mDeviceId == DEVICE_CEC)
{
cfg.append_attribute("type") = "cec";
cfg.append_attribute("deviceName") = "CEC";
}
else
{
2013-04-11 22:27:27 +00:00
cfg.append_attribute("type") = "joystick";
cfg.append_attribute("deviceName") = mDeviceName.c_str();
}
2013-04-11 22:27:27 +00:00
cfg.append_attribute("deviceGUID") = mDeviceGUID.c_str();
2017-11-11 14:56:22 +00:00
typedef std::map<std::string, Input>::const_iterator it_type;
for(it_type iterator = mNameMap.cbegin(); iterator != mNameMap.cend(); iterator++)
2013-04-11 22:27:27 +00:00
{
if(!iterator->second.configured)
continue;
2013-04-11 22:27:27 +00:00
pugi::xml_node input = cfg.append_child("input");
input.append_attribute("name") = iterator->first.c_str();
input.append_attribute("type") = inputTypeToString(iterator->second.type).c_str();
input.append_attribute("id").set_value(iterator->second.id);
input.append_attribute("value").set_value(iterator->second.value);
}
}