Load joystick mappings from json.

This commit is contained in:
Christian Speckner 2020-11-16 22:26:25 +01:00
parent 4314c0cdeb
commit fdc07b3eac
6 changed files with 96 additions and 24 deletions

View File

@ -93,6 +93,11 @@
"vector": "cpp",
"memory_resource": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp"
"cinttypes": "cpp",
"filesystem": "cpp",
"forward_list": "cpp",
"regex": "cpp",
"valarray": "cpp",
"ranges": "cpp"
}
}

View File

@ -17,6 +17,7 @@
#include "JoyMap.hxx"
#include "jsonDefinitions.hxx"
#include "Logger.hxx"
using json = nlohmann::json;
@ -209,6 +210,31 @@ json JoyMap::saveMapping(const EventMode mode) const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int JoyMap::loadMapping(const json& eventMappings, const EventMode mode)
{
int i = 0;
for (const json& eventMapping: eventMappings) {
try {
add(
eventMapping.at("event").get<Event::Type>(),
mode,
eventMapping.at("button").get<int>(),
eventMapping.at("axis").get<JoyAxis>(),
eventMapping.at("axisDirection").get<JoyDir>(),
eventMapping.at("hat").get<int>(),
eventMapping.at("hatDirection").get<JoyHatDir>()
);
i++;
} catch (json::exception) {
Logger::error("ignoring invalid joystick event");
}
}
return i;
}
#if 0
int JoyMap::loadMapping(string& list, const EventMode mode)
{
// Since istringstream swallows whitespace, we have to make the
@ -226,6 +252,7 @@ int JoyMap::loadMapping(string& list, const EventMode mode)
return i;
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JoyMap::eraseMode(const EventMode mode)

View File

@ -112,7 +112,7 @@ class JoyMap
JoyMappingArray getEventMapping(const Event::Type event, const EventMode mode) const;
nlohmann::json saveMapping(const EventMode mode) const;
int loadMapping(string& list, const EventMode mode);
int loadMapping(const nlohmann::json& eventMappings, const EventMode mode);
/** Erase all mappings for given mode */
void eraseMode(const EventMode mode);

View File

@ -22,13 +22,12 @@
#include "Settings.hxx"
#include "EventHandler.hxx"
#include "PJoystickHandler.hxx"
#include "Logger.hxx"
#ifdef GUI_SUPPORT
#include "DialogContainer.hxx"
#endif
static constexpr char CTRL_DELIM = '^';
using json = nlohmann::json;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -37,25 +36,29 @@ PhysicalJoystickHandler::PhysicalJoystickHandler(
: myOSystem(system),
myHandler(handler)
{
Int32 version = myOSystem.settings().getInt("event_ver");
// Load previously saved joystick mapping (if any) from settings
istringstream buf(myOSystem.settings().getString("joymap"));
string joymap, joyname;
if(myOSystem.settings().getInt("event_ver") != Event::VERSION) {
Logger::info("event version mismatch; dropping previous joystick mappings");
// First compare if event list version has changed, and disregard the entire
// mapping if true
getline(buf, joymap, CTRL_DELIM); // event list size, ignore
if(version == Event::VERSION)
{
// Otherwise, put each joystick mapping entry into the database
while(getline(buf, joymap, CTRL_DELIM))
{
istringstream namebuf(joymap);
getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM);
if(joyname.length() != 0)
// TODO: convert old mapping to json
myDatabase.emplace(joyname, StickInfo());
return;
}
json mappings;
try {
mappings = json::parse(myOSystem.settings().getString("joymap"));
} catch (json::exception) {
// TODO: error handling + migration
mappings = json::array();
}
for (const json& mapping: mappings) {
if (!mapping.contains("name")) {
Logger::error("igmoring bad joystick mapping");
continue;
}
myDatabase.emplace(mapping.at("name").get<string>(), StickInfo(mapping));
}
}

View File

@ -23,14 +23,21 @@
#include "bspf.hxx"
#include "PhysicalJoystick.hxx"
#include "jsonDefinitions.hxx"
#include "Logger.hxx"
using json = nlohmann::json;
namespace {
string jsonName(EventMode eventMode) {
json serializedName = eventMode;
return json(eventMode).get<string>();
}
return serializedName.get<string>();
EventMode eventModeFromJsonName(const string& name) {
EventMode result;
from_json(json(name), result);
return result;
}
}
@ -71,6 +78,35 @@ json PhysicalJoystick::getMap() const
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PhysicalJoystick::setMap(const json& map)
{
int i = 0;
for (auto& entry: map.items()) {
if (entry.key() == "name") continue;
try {
joyMap.loadMapping(entry.value(), eventModeFromJsonName(entry.key()));
} catch (json::exception) {
Logger::error("ignoring invalid json mapping for " + entry.key());
}
i++;
}
if(i != 5)
{
Logger::error("invalid controller mappings found for " +
((map.contains("name") && map.at("name").is_string()) ? ("stick " + map["name"].get<string>()) : "unknown stick")
);
return false;
}
return true;
}
#if 0
bool PhysicalJoystick::setMap(const string& mapString)
{
istringstream buf(mapString);
@ -104,6 +140,7 @@ bool PhysicalJoystick::setMap(const string& mapString)
return true;
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PhysicalJoystick::eraseMap(EventMode mode)

View File

@ -46,7 +46,7 @@ class PhysicalJoystick
PhysicalJoystick() = default;
nlohmann::json getMap() const;
bool setMap(const string& map);
bool setMap(const nlohmann::json& map);
void eraseMap(EventMode mode);
void eraseEvent(Event::Type event, EventMode mode);
string about() const;