Merge branch 'master' into feature-highscores

This commit is contained in:
thrust26 2020-11-28 22:03:54 +01:00
commit 311e25179c
17 changed files with 28028 additions and 136 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"
}
}

7
configure vendored
View File

@ -580,6 +580,10 @@ else
darwin*)
DEFINES="$DEFINES -DUNIX -DDARWIN"
_host_os=darwin
if test "$have_clang" = yes; then
CXXFLAGS="$CXXFLAGS -Wno-documentation-unknown-command -Wno-documentation-pedantic -Wno-poison-system-directories"
CXXFLAGS="$CXXFLAGS -Wno-unknown-warning-option"
fi
;;
irix*)
DEFINES="$DEFINES -DUNIX"
@ -821,8 +825,9 @@ CHEAT="$SRC/cheat"
LIBPNG="$SRC/libpng"
ZLIB="$SRC/zlib"
SQLITE="$SRC/common/repository/sqlite"
JSON="$SRC/json"
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER"
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$JSON"
INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
if test "$_build_static" = yes ; then

View File

@ -16,6 +16,10 @@
//============================================================================
#include "JoyMap.hxx"
#include "jsonDefinitions.hxx"
#include "Logger.hxx"
using json = nlohmann::json;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JoyMap::add(const Event::Type event, const JoyMapping& mapping)
@ -183,67 +187,105 @@ JoyMap::JoyMappingArray JoyMap::getEventMapping(const Event::Type event, const E
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string JoyMap::saveMapping(const EventMode mode) const
json JoyMap::saveMapping(const EventMode mode) const
{
using MapType = std::pair<JoyMapping, Event::Type>;
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
json eventMappings = json::array();
std::sort(sortedMap.begin(), sortedMap.end(),
[](const MapType& a, const MapType& b)
{
// Event::Type first
if(a.second != b.second)
return a.second < b.second;
for (auto& item: myMap) {
if (item.first.mode != mode) continue;
if(a.first.button != b.first.button)
return a.first.button < b.first.button;
json eventMapping = json::object();
if(a.first.axis != b.first.axis)
return a.first.axis < b.first.axis;
eventMapping["event"] = item.second;
if(a.first.adir != b.first.adir)
return a.first.adir < b.first.adir;
if (item.first.button != JOY_CTRL_NONE) eventMapping["button"] = item.first.button;
if(a.first.hat != b.first.hat)
return a.first.hat < b.first.hat;
return a.first.hdir < b.first.hdir;
if (item.first.axis != JoyAxis::NONE) {
eventMapping["axis"] = item.first.axis;
eventMapping["axisDirection"] = item.first.adir;
}
);
ostringstream buf;
for (auto item : sortedMap)
{
if (item.first.mode == mode)
{
if (buf.str() != "")
buf << "|";
buf << item.second << ":" << item.first.button << ","
<< int(item.first.axis) << "," << int(item.first.adir) << ","
<< item.first.hat << "," << int(item.first.hdir);
if (item.first.hat != -1) {
eventMapping["hat"] = item.first.hat;
eventMapping["hatDirection"] = item.first.hdir;
}
eventMappings.push_back(eventMapping);
}
return buf.str();
return eventMappings;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int JoyMap::loadMapping(string& list, const EventMode mode)
int JoyMap::loadMapping(const json& eventMappings, const EventMode mode)
{
int i = 0;
for (const json& eventMapping: eventMappings) {
int button = eventMapping.contains("button") ? eventMapping.at("button").get<int>() : JOY_CTRL_NONE;
JoyAxis axis = eventMapping.contains("axis") ? eventMapping.at("axis").get<JoyAxis>() : JoyAxis::NONE;
JoyDir axisDirection = eventMapping.contains("axis") ? eventMapping.at("axisDirection").get<JoyDir>() : JoyDir::NONE;
int hat = eventMapping.contains("hat") ? eventMapping.at("hat").get<int>() : -1;
JoyHatDir hatDirection = eventMapping.contains("hat") ? eventMapping.at("hatDirection").get<JoyHatDir>() : JoyHatDir::CENTER;
try {
add(
eventMapping.at("event").get<Event::Type>(),
mode,
button,
axis,
axisDirection,
hat,
hatDirection
);
i++;
} catch (json::exception) {
Logger::error("ignoring invalid joystick event");
}
}
return i;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
json JoyMap::convertLegacyMapping(string list)
{
json eventMappings = json::array();
// Since istringstream swallows whitespace, we have to make the
// delimiters be spaces
std::replace(list.begin(), list.end(), '|', ' ');
std::replace(list.begin(), list.end(), ':', ' ');
std::replace(list.begin(), list.end(), ',', ' ');
istringstream buf(list);
int event, button, axis, adir, hat, hdir, i = 0;
int event, button, axis, adir, hat, hdir;
while (buf >> event && buf >> button
&& buf >> axis && buf >> adir
&& buf >> hat && buf >> hdir && ++i)
add(Event::Type(event), EventMode(mode), button, JoyAxis(axis), JoyDir(adir), hat, JoyHatDir(hdir));
&& buf >> hat && buf >> hdir)
{
json eventMapping = json::object();
return i;
eventMapping["event"] = Event::Type(event);
if (button != JOY_CTRL_NONE) eventMapping["button"] = button;
if (JoyAxis(axis) != JoyAxis::NONE) {
eventMapping["axis"] = JoyAxis(axis);
eventMapping["axisDirection"] = JoyDir(adir);
}
if (hat != -1) {
eventMapping["hat"] = hat;
eventMapping["hatDirection"] = JoyHatDir(hdir);
}
eventMappings.push_back(eventMapping);
}
return eventMappings;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -22,6 +22,7 @@
#include "Event.hxx"
#include "EventHandlerConstants.hxx"
#include "json.hxx"
/**
This class handles controller mappings in Stella.
@ -110,8 +111,10 @@ class JoyMap
JoyMappingArray getEventMapping(const Event::Type event, const EventMode mode) const;
string saveMapping(const EventMode mode) const;
int loadMapping(string& list, const EventMode mode);
nlohmann::json saveMapping(const EventMode mode) const;
int loadMapping(const nlohmann::json& eventMappings, const EventMode mode);
static nlohmann::json convertLegacyMapping(string list);
/** Erase all mappings for given mode */
void eraseMode(const EventMode mode);

View File

@ -16,8 +16,12 @@
//============================================================================
#include "KeyMap.hxx"
#include "Logger.hxx"
#include "jsonDefinitions.hxx"
#include <map>
using json = nlohmann::json;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void KeyMap::add(const Event::Type event, const Mapping& mapping)
{
@ -169,54 +173,74 @@ KeyMap::MappingArray KeyMap::getEventMapping(const Event::Type event, const Even
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string KeyMap::saveMapping(const EventMode mode) const
json KeyMap::saveMapping(const EventMode mode) const
{
using MapType = std::pair<Mapping, Event::Type>;
std::vector<MapType> sortedMap(myMap.begin(), myMap.end());
json mappings = json::array();
std::sort(sortedMap.begin(), sortedMap.end(),
[](const MapType& a, const MapType& b)
{
// Event::Type first
if(a.second != b.second)
return a.second < b.second;
for (auto item : myMap) {
if (item.first.mode != mode) continue;
if(a.first.key != b.first.key)
return a.first.key < b.first.key;
json mapping = json::object();
return a.first.mod < b.first.mod;
}
);
mapping["event"] = item.second;
mapping["key"] = item.first.key;
ostringstream buf;
if (item.first.mod != StellaMod::KBDM_NONE)
mapping["mod"] = item.first.mod;
for (auto item : sortedMap)
{
if (item.first.mode == mode)
{
if (buf.str() != "")
buf << "|";
buf << item.second << ":" << item.first.key << "," << item.first.mod;
}
mappings.push_back(mapping);
}
return buf.str();
return mappings;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int KeyMap::loadMapping(string& list, const EventMode mode)
int KeyMap::loadMapping(const json& mappings, const EventMode mode) {
int i = 0;
for (const json& mapping: mappings) {
try {
add(
mapping.at("event").get<Event::Type>(),
mode,
mapping.at("key").get<StellaKey>(),
mapping.contains("mod") ? mapping.at("mod").get<StellaMod>() : StellaMod::KBDM_NONE
);
i++;
} catch (json::exception) {
Logger::error("ignoring bad keyboard mapping");
}
}
return i;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
json KeyMap::convertLegacyMapping(string list)
{
json convertedMapping = json::array();
// Since istringstream swallows whitespace, we have to make the
// delimiters be spaces
std::replace(list.begin(), list.end(), '|', ' ');
std::replace(list.begin(), list.end(), ':', ' ');
std::replace(list.begin(), list.end(), ',', ' ');
istringstream buf(list);
int event, key, mod, i = 0;
int event, key, mod;
while (buf >> event && buf >> key && buf >> mod && ++i)
add(Event::Type(event), mode, key, mod);
while (buf >> event && buf >> key && buf >> mod) {
json mapping = json::object();
return i;
mapping["event"] = Event::Type(event);
mapping["key"] = StellaKey(key);
if (StellaMod(mod) != StellaMod::KBDM_NONE) mapping["mod"] = StellaMod(mod);
convertedMapping.push_back(mapping);
}
return convertedMapping;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -22,6 +22,7 @@
#include "Event.hxx"
#include "EventHandlerConstants.hxx"
#include "StellaKeys.hxx"
#include "json.hxx"
/**
This class handles keyboard mappings in Stella.
@ -86,8 +87,10 @@ class KeyMap
MappingArray getEventMapping(const Event::Type event, const EventMode mode) const;
string saveMapping(const EventMode mode) const;
int loadMapping(string& list, const EventMode mode);
nlohmann::json saveMapping(const EventMode mode) const;
int loadMapping(const nlohmann::json& mapping, const EventMode mode);
static nlohmann::json convertLegacyMapping(string list);
/** Erase all mappings for given mode */
void eraseMode(const EventMode mode);

View File

@ -22,12 +22,13 @@
#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;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PhysicalJoystickHandler::PhysicalJoystickHandler(
@ -35,25 +36,54 @@ 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"));
if(myOSystem.settings().getInt("event_ver") != Event::VERSION) {
Logger::info("event version mismatch; dropping previous joystick mappings");
return;
}
json mappings;
const string& serializedMapping = myOSystem.settings().getString("joymap");
try {
mappings = json::parse(serializedMapping);
} catch (json::exception) {
Logger::info("converting legacy joystick mappings");
mappings = convertLegacyMapping(serializedMapping);
}
for (const json& mapping: mappings) {
if (!mapping.contains("name")) {
Logger::error("ignoring bad joystick mapping");
continue;
}
myDatabase.emplace(mapping.at("name").get<string>(), StickInfo(mapping));
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
json PhysicalJoystickHandler::convertLegacyMapping(const string& mapping)
{
constexpr char CTRL_DELIM = '^';
istringstream buf(mapping);
string joymap, joyname;
// 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)
json convertedMapping = json::array();
while(getline(buf, joymap, CTRL_DELIM))
{
// 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)
myDatabase.emplace(joyname, StickInfo(joymap));
}
istringstream namebuf(joymap);
getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM);
convertedMapping.push_back(PhysicalJoystick::convertLegacyMapping(joymap, joyname));
}
return convertedMapping;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -526,15 +556,16 @@ void PhysicalJoystickHandler::saveMapping()
{
// Save the joystick mapping hash table, making sure to update it with
// any changes that have been made during the program run
ostringstream joybuf;
json mapping = json::array();
for(const auto& i: myDatabase)
{
const string& map = i.second.joy ? i.second.joy->getMap() : i.second.mapping;
if(map != "")
joybuf << CTRL_DELIM << map;
json map = i.second.joy ? i.second.joy->getMap() : i.second.mapping;
if (!map.is_null()) mapping.emplace_back(map);
}
myOSystem.settings().setValue("joymap", joybuf.str());
myOSystem.settings().setValue("joymap", mapping.dump());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -28,6 +28,7 @@ class Event;
#include "EventHandlerConstants.hxx"
#include "PhysicalJoystick.hxx"
#include "Variant.hxx"
#include "json.hxx"
using PhysicalJoystickPtr = shared_ptr<PhysicalJoystick>;
@ -48,10 +49,10 @@ class PhysicalJoystickHandler
private:
struct StickInfo
{
StickInfo(const string& map = EmptyString, PhysicalJoystickPtr stick = nullptr)
StickInfo(const nlohmann::json& map = nullptr, PhysicalJoystickPtr stick = nullptr)
: mapping(map), joy(std::move(stick)) {}
string mapping;
nlohmann::json mapping;
PhysicalJoystickPtr joy;
friend ostream& operator<<(ostream& os, const StickInfo& si) {
@ -63,6 +64,8 @@ class PhysicalJoystickHandler
public:
PhysicalJoystickHandler(OSystem& system, EventHandler& handler);
static nlohmann::json convertLegacyMapping(const string& mapping);
/** Return stick ID on success, -1 on failure. */
int add(const PhysicalJoystickPtr& stick);
bool remove(int id);

View File

@ -19,6 +19,9 @@
#include "Console.hxx"
#include "EventHandler.hxx"
#include "PKeyboardHandler.hxx"
#include "json.hxx"
using json = nlohmann::json;
#ifdef DEBUGGER_SUPPORT
#include "Debugger.hxx"
@ -46,18 +49,15 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler&
// Compare if event list version has changed so that key maps became invalid
if (version == Event::VERSION)
{
string list = myOSystem.settings().getString("keymap_emu");
myKeyMap.loadMapping(list, EventMode::kCommonMode);
list = myOSystem.settings().getString("keymap_joy");
myKeyMap.loadMapping(list, EventMode::kJoystickMode);
list = myOSystem.settings().getString("keymap_pad");
myKeyMap.loadMapping(list, EventMode::kPaddlesMode);
list = myOSystem.settings().getString("keymap_key");
myKeyMap.loadMapping(list, EventMode::kKeypadMode);
list = myOSystem.settings().getString("keymap_ui");
myKeyMap.loadMapping(list, EventMode::kMenuMode);
loadSerializedMappings(myOSystem.settings().getString("keymap_emu"), EventMode::kCommonMode);
loadSerializedMappings(myOSystem.settings().getString("keymap_joy"), EventMode::kJoystickMode);
loadSerializedMappings(myOSystem.settings().getString("keymap_pad"), EventMode::kPaddlesMode);
loadSerializedMappings(myOSystem.settings().getString("keymap_key"), EventMode::kKeypadMode);
loadSerializedMappings(myOSystem.settings().getString("keymap_ui"), EventMode::kMenuMode);
updateDefaults = true;
}
myKeyMap.enableMod() = myOSystem.settings().getBool("modcombo");
setDefaultMapping(Event::NoType, EventMode::kEmulationMode, updateDefaults);
@ -67,6 +67,26 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(OSystem& system, EventHandler&
#endif // DEBUG
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PhysicalKeyboardHandler::loadSerializedMappings(const string& serializedMapping, EventMode mode)
{
json mapping;
try {
mapping = json::parse(serializedMapping);
} catch (json::exception) {
Logger::info("converting legacy keyboard mappings");
mapping = KeyMap::convertLegacyMapping(serializedMapping);
}
try {
myKeyMap.loadMapping(mapping, mode);
} catch (json::exception) {
Logger::error("ignoring bad keyboard mappings");
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PhysicalKeyboardHandler::isMappingUsed(EventMode mode, const EventMapping& map) const
{
@ -357,11 +377,11 @@ void PhysicalKeyboardHandler::eraseMapping(Event::Type event, EventMode mode)
void PhysicalKeyboardHandler::saveMapping()
{
myOSystem.settings().setValue("event_ver", Event::VERSION);
myOSystem.settings().setValue("keymap_emu", myKeyMap.saveMapping(EventMode::kCommonMode));
myOSystem.settings().setValue("keymap_joy", myKeyMap.saveMapping(EventMode::kJoystickMode));
myOSystem.settings().setValue("keymap_pad", myKeyMap.saveMapping(EventMode::kPaddlesMode));
myOSystem.settings().setValue("keymap_key", myKeyMap.saveMapping(EventMode::kKeypadMode));
myOSystem.settings().setValue("keymap_ui", myKeyMap.saveMapping(EventMode::kMenuMode));
myOSystem.settings().setValue("keymap_emu", myKeyMap.saveMapping(EventMode::kCommonMode).dump());
myOSystem.settings().setValue("keymap_joy", myKeyMap.saveMapping(EventMode::kJoystickMode).dump());
myOSystem.settings().setValue("keymap_pad", myKeyMap.saveMapping(EventMode::kPaddlesMode).dump());
myOSystem.settings().setValue("keymap_key", myKeyMap.saveMapping(EventMode::kKeypadMode).dump());
myOSystem.settings().setValue("keymap_ui", myKeyMap.saveMapping(EventMode::kMenuMode).dump());
enableEmulationMappings();
}

View File

@ -45,6 +45,8 @@ class PhysicalKeyboardHandler
PhysicalKeyboardHandler(OSystem& system, EventHandler& handler);
void loadSerializedMappings(const string& serializedMappings, EventMode mode);
void setDefaultMapping(Event::Type type, EventMode mode, bool updateDefaults = false);
/** define mappings for current controllers */

View File

@ -22,6 +22,24 @@
#include "Vec.hxx"
#include "bspf.hxx"
#include "PhysicalJoystick.hxx"
#include "jsonDefinitions.hxx"
#include "Logger.hxx"
using json = nlohmann::json;
namespace {
string jsonName(EventMode eventMode) {
return json(eventMode).get<string>();
}
EventMode eventModeFromJsonName(const string& name) {
EventMode result;
from_json(json(name), result);
return result;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PhysicalJoystick::initialize(int index, const string& desc,
@ -45,30 +63,56 @@ void PhysicalJoystick::initialize(int index, const string& desc,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string PhysicalJoystick::getMap() const
json PhysicalJoystick::getMap() const
{
// The mapping structure (for remappable devices) is defined as follows:
// <NAME>'>'<MODE>['|'(<EVENT>':'<BUTTON>','<AXIS>','<VALUE>)|(<EVENT>':'<BUTTON>','<HAT>','<HATDIR>)]
json mapping = json::object();
ostringstream joybuf;
mapping["name"] = name;
joybuf << name;
joybuf << MODE_DELIM << int(EventMode::kMenuMode) << "|" << joyMap.saveMapping(EventMode::kMenuMode);
joybuf << MODE_DELIM << int(EventMode::kJoystickMode) << "|" << joyMap.saveMapping(EventMode::kJoystickMode);
joybuf << MODE_DELIM << int(EventMode::kPaddlesMode) << "|" << joyMap.saveMapping(EventMode::kPaddlesMode);
joybuf << MODE_DELIM << int(EventMode::kKeypadMode) << "|" << joyMap.saveMapping(EventMode::kKeypadMode);
joybuf << MODE_DELIM << int(EventMode::kCommonMode) << "|" << joyMap.saveMapping(EventMode::kCommonMode);
for (auto& mode: {
EventMode::kMenuMode, EventMode::kJoystickMode, EventMode::kPaddlesMode, EventMode::kKeypadMode, EventMode::kCommonMode
})
mapping[jsonName(mode)] = joyMap.saveMapping(mode);
return joybuf.str();
return mapping;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PhysicalJoystick::setMap(const string& mapString)
bool PhysicalJoystick::setMap(const json& map)
{
istringstream buf(mapString);
string 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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
json PhysicalJoystick::convertLegacyMapping(const string& mapping, const string& name)
{
istringstream buf(mapping);
json convertedMapping = json::object();
string map;
// Skip joystick name
getline(buf, map, MODE_DELIM);
@ -84,17 +128,14 @@ bool PhysicalJoystick::setMap(const string& mapString)
// Remove leading "<mode>|" string
map.erase(0, 2);
joyMap.loadMapping(map, EventMode(mode));
i++;
}
// Brief error checking
if(i != 5)
{
cerr << "ERROR: Invalid controller mappings found" << endl;
return false;
json mappingForMode = JoyMap::convertLegacyMapping(map);
convertedMapping[jsonName(EventMode(mode))] = mappingForMode;
}
return true;
convertedMapping["name"] = name;
return convertedMapping;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -21,6 +21,7 @@
#include "Event.hxx"
#include "EventHandlerConstants.hxx"
#include "JoyMap.hxx"
#include "json.hxx"
/**
An abstraction of a physical (real) joystick in Stella.
@ -44,8 +45,11 @@ class PhysicalJoystick
public:
PhysicalJoystick() = default;
string getMap() const;
bool setMap(const string& map);
nlohmann::json getMap() const;
bool setMap(const nlohmann::json& map);
static nlohmann::json convertLegacyMapping(const string& mapping, const string& name);
void eraseMap(EventMode mode);
void eraseEvent(Event::Type event, EventMode mode);
string about() const;

View File

@ -0,0 +1,609 @@
#ifndef JSON_DEFINITIONS_HXX
#define JSON_DEFINITIONS_HXX
#include "EventHandlerConstants.hxx"
#include "Event.hxx"
#include "json.hxx"
#include "StellaKeys.hxx"
NLOHMANN_JSON_SERIALIZE_ENUM(JoyAxis, {
{JoyAxis::NONE, nullptr},
{JoyAxis::X, "x"},
{JoyAxis::Y, "y"},
{JoyAxis::Z, "z"},
{JoyAxis::A3, "a3"}
})
NLOHMANN_JSON_SERIALIZE_ENUM(JoyDir, {
{JoyDir::NONE, nullptr},
{JoyDir::ANALOG, "analog"},
{JoyDir::NEG, "negative"},
{JoyDir::POS, "position"}
})
NLOHMANN_JSON_SERIALIZE_ENUM(JoyHatDir, {
{JoyHatDir::CENTER, "center"},
{JoyHatDir::DOWN, "down"},
{JoyHatDir::LEFT, "left"},
{JoyHatDir::RIGHT, "right"},
{JoyHatDir::UP, "up"}
});
NLOHMANN_JSON_SERIALIZE_ENUM(EventMode, {
{EventMode::kEditMode, "kEditMode"},
{EventMode::kMenuMode, "kMenuMode"},
{EventMode::kEmulationMode, "kEmulationMode"},
{EventMode::kJoystickMode, "kJoystickMode"},
{EventMode::kPaddlesMode, "kPaddlesMode"},
{EventMode::kKeypadMode, "kKeypadMode"},
{EventMode::kCompuMateMode, "kCompuMateMode"},
{EventMode::kCommonMode, "kCommonMode"},
{EventMode::kNumModes, "kNumModes"},
});
NLOHMANN_JSON_SERIALIZE_ENUM(Event::Type, {
{Event::NoType, "NoType"},
{Event::ConsoleColor, "ConsoleColor"},
{Event::ConsoleBlackWhite, "ConsoleBlackWhite"},
{Event::ConsoleColorToggle, "ConsoleColorToggle"},
{Event::Console7800Pause, "Console7800Pause"},
{Event::ConsoleLeftDiffA, "ConsoleLeftDiffA"},
{Event::ConsoleLeftDiffB, "ConsoleLeftDiffB"},
{Event::ConsoleLeftDiffToggle, "ConsoleLeftDiffToggle"},
{Event::ConsoleRightDiffA, "ConsoleRightDiffA"},
{Event::ConsoleRightDiffB, "ConsoleRightDiffB"},
{Event::ConsoleRightDiffToggle, "ConsoleRightDiffToggle"},
{Event::ConsoleSelect, "ConsoleSelect"},
{Event::ConsoleReset, "ConsoleReset"},
{Event::JoystickZeroUp, "JoystickZeroUp"},
{Event::JoystickZeroDown, "JoystickZeroDown"},
{Event::JoystickZeroLeft, "JoystickZeroLeft"},
{Event::JoystickZeroRight, "JoystickZeroRight"},
{Event::JoystickZeroFire, "JoystickZeroFire"},
{Event::JoystickZeroFire5, "JoystickZeroFire5"},
{Event::JoystickZeroFire9, "JoystickZeroFire9"},
{Event::JoystickOneUp, "JoystickOneUp"},
{Event::JoystickOneDown, "JoystickOneDown"},
{Event::JoystickOneLeft, "JoystickOneLeft"},
{Event::JoystickOneRight, "JoystickOneRight"},
{Event::JoystickOneFire, "JoystickOneFire"},
{Event::JoystickOneFire5, "JoystickOneFire5"},
{Event::JoystickOneFire9, "JoystickOneFire9"},
{Event::PaddleZeroDecrease, "PaddleZeroDecrease"},
{Event::PaddleZeroIncrease, "PaddleZeroIncrease"},
{Event::PaddleZeroAnalog, "PaddleZeroAnalog"},
{Event::PaddleZeroFire, "PaddleZeroFire"},
{Event::PaddleOneDecrease, "PaddleOneDecrease"},
{Event::PaddleOneIncrease, "PaddleOneIncrease"},
{Event::PaddleOneAnalog, "PaddleOneAnalog"},
{Event::PaddleOneFire, "PaddleOneFire"},
{Event::PaddleTwoDecrease, "PaddleTwoDecrease"},
{Event::PaddleTwoIncrease, "PaddleTwoIncrease"},
{Event::PaddleTwoAnalog, "PaddleTwoAnalog"},
{Event::PaddleTwoFire, "PaddleTwoFire"},
{Event::PaddleThreeDecrease, "PaddleThreeDecrease"},
{Event::PaddleThreeIncrease, "PaddleThreeIncrease"},
{Event::PaddleThreeAnalog, "PaddleThreeAnalog"},
{Event::PaddleThreeFire, "PaddleThreeFire"},
{Event::KeyboardZero1, "KeyboardZero1"},
{Event::KeyboardZero2, "KeyboardZero2"},
{Event::KeyboardZero3, "KeyboardZero3"},
{Event::KeyboardZero4, "KeyboardZero4"},
{Event::KeyboardZero5, "KeyboardZero5"},
{Event::KeyboardZero6, "KeyboardZero6"},
{Event::KeyboardZero7, "KeyboardZero7"},
{Event::KeyboardZero8, "KeyboardZero8"},
{Event::KeyboardZero9, "KeyboardZero9"},
{Event::KeyboardZeroStar, "KeyboardZeroStar"},
{Event::KeyboardZero0, "KeyboardZero0"},
{Event::KeyboardZeroPound, "KeyboardZeroPound"},
{Event::KeyboardOne1, "KeyboardOne1"},
{Event::KeyboardOne2, "KeyboardOne2"},
{Event::KeyboardOne3, "KeyboardOne3"},
{Event::KeyboardOne4, "KeyboardOne4"},
{Event::KeyboardOne5, "KeyboardOne5"},
{Event::KeyboardOne6, "KeyboardOne6"},
{Event::KeyboardOne7, "KeyboardOne7"},
{Event::KeyboardOne8, "KeyboardOne8"},
{Event::KeyboardOne9, "KeyboardOne9"},
{Event::KeyboardOneStar, "KeyboardOneStar"},
{Event::KeyboardOne0, "KeyboardOne0"},
{Event::KeyboardOnePound, "KeyboardOnePound"},
{Event::CompuMateFunc, "CompuMateFunc"},
{Event::CompuMateShift, "CompuMateShift"},
{Event::CompuMate0, "CompuMate0"},
{Event::CompuMate1, "CompuMate1"},
{Event::CompuMate2, "CompuMate2"},
{Event::CompuMate3, "CompuMate3"},
{Event::CompuMate4, "CompuMate4"},
{Event::CompuMate5, "CompuMate5"},
{Event::CompuMate6, "CompuMate6"},
{Event::CompuMate7, "CompuMate7"},
{Event::CompuMate8, "CompuMate8"},
{Event::CompuMate9, "CompuMate9"},
{Event::CompuMateA, "CompuMateA"},
{Event::CompuMateB, "CompuMateB"},
{Event::CompuMateC, "CompuMateC"},
{Event::CompuMateD, "CompuMateD"},
{Event::CompuMateE, "CompuMateE"},
{Event::CompuMateF, "CompuMateF"},
{Event::CompuMateG, "CompuMateG"},
{Event::CompuMateH, "CompuMateH"},
{Event::CompuMateI, "CompuMateI"},
{Event::CompuMateJ, "CompuMateJ"},
{Event::CompuMateK, "CompuMateK"},
{Event::CompuMateL, "CompuMateL"},
{Event::CompuMateM, "CompuMateM"},
{Event::CompuMateN, "CompuMateN"},
{Event::CompuMateO, "CompuMateO"},
{Event::CompuMateP, "CompuMateP"},
{Event::CompuMateQ, "CompuMateQ"},
{Event::CompuMateR, "CompuMateR"},
{Event::CompuMateS, "CompuMateS"},
{Event::CompuMateT, "CompuMateT"},
{Event::CompuMateU, "CompuMateU"},
{Event::CompuMateV, "CompuMateV"},
{Event::CompuMateW, "CompuMateW"},
{Event::CompuMateX, "CompuMateX"},
{Event::CompuMateY, "CompuMateY"},
{Event::CompuMateZ, "CompuMateZ"},
{Event::CompuMateComma, "CompuMateComma"},
{Event::CompuMatePeriod, "CompuMatePeriod"},
{Event::CompuMateEnter, "CompuMateEnter"},
{Event::CompuMateSpace, "CompuMateSpace"},
{Event::CompuMateQuestion, "CompuMateQuestion"},
{Event::CompuMateLeftBracket, "CompuMateLeftBracket"},
{Event::CompuMateRightBracket, "CompuMateRightBracket"},
{Event::CompuMateMinus, "CompuMateMinus"},
{Event::CompuMateQuote, "CompuMateQuote"},
{Event::CompuMateBackspace, "CompuMateBackspace"},
{Event::CompuMateEquals, "CompuMateEquals"},
{Event::CompuMatePlus, "CompuMatePlus"},
{Event::CompuMateSlash, "CompuMateSlash"},
{Event::Combo1, "Combo1"},
{Event::Combo2, "Combo2"},
{Event::Combo3, "Combo3"},
{Event::Combo4, "Combo4"},
{Event::Combo5, "Combo5"},
{Event::Combo6, "Combo6"},
{Event::Combo7, "Combo7"},
{Event::Combo8, "Combo8"},
{Event::Combo9, "Combo9"},
{Event::Combo10, "Combo10"},
{Event::Combo11, "Combo11"},
{Event::Combo12, "Combo12"},
{Event::Combo13, "Combo13"},
{Event::Combo14, "Combo14"},
{Event::Combo15, "Combo15"},
{Event::Combo16, "Combo16"},
{Event::UIUp, "UIUp"},
{Event::UIDown, "UIDown"},
{Event::UILeft, "UILeft"},
{Event::UIRight, "UIRight"},
{Event::UIHome, "UIHome"},
{Event::UIEnd, "UIEnd"},
{Event::UIPgUp, "UIPgUp"},
{Event::UIPgDown, "UIPgDown"},
{Event::UISelect, "UISelect"},
{Event::UINavPrev, "UINavPrev"},
{Event::UINavNext, "UINavNext"},
{Event::UIOK, "UIOK"},
{Event::UICancel, "UICancel"},
{Event::UIPrevDir, "UIPrevDir"},
{Event::UITabPrev, "UITabPrev"},
{Event::UITabNext, "UITabNext"},
{Event::HandleMouseControl, "HandleMouseControl"},
{Event::ToggleGrabMouse, "ToggleGrabMouse"},
{Event::MouseAxisXMove, "MouseAxisXMove"},
{Event::MouseAxisYMove, "MouseAxisYMove"},
{Event::MouseAxisXValue, "MouseAxisXValue"},
{Event::MouseAxisYValue, "MouseAxisYValue"},
{Event::MouseButtonLeftValue, "MouseButtonLeftValue"},
{Event::MouseButtonRightValue, "MouseButtonRightValue"},
{Event::Quit, "Quit"},
{Event::ReloadConsole, "ReloadConsole"},
{Event::Fry, "Fry"},
{Event::TogglePauseMode, "TogglePauseMode"},
{Event::StartPauseMode, "StartPauseMode"},
{Event::OptionsMenuMode, "OptionsMenuMode"},
{Event::CmdMenuMode, "CmdMenuMode"},
{Event::DebuggerMode, "DebuggerMode"},
{Event::ExitMode, "ExitMode"},
{Event::TakeSnapshot, "TakeSnapshot"},
{Event::ToggleContSnapshots, "ToggleContSnapshots"},
{Event::ToggleContSnapshotsFrame, "ToggleContSnapshotsFrame"},
{Event::ToggleTurbo, "ToggleTurbo"},
{Event::NextState, "NextState"},
{Event::PreviousState, "PreviousState"},
{Event::LoadState, "LoadState"},
{Event::SaveState, "SaveState"},
{Event::SaveAllStates, "SaveAllStates"},
{Event::LoadAllStates, "LoadAllStates"},
{Event::ToggleAutoSlot, "ToggleAutoSlot"},
{Event::ToggleTimeMachine, "ToggleTimeMachine"},
{Event::TimeMachineMode, "TimeMachineMode"},
{Event::Rewind1Menu, "Rewind1Menu"},
{Event::Rewind10Menu, "Rewind10Menu"},
{Event::RewindAllMenu, "RewindAllMenu"},
{Event::Unwind1Menu, "Unwind1Menu"},
{Event::Unwind10Menu, "Unwind10Menu"},
{Event::UnwindAllMenu, "UnwindAllMenu"},
{Event::RewindPause, "RewindPause"},
{Event::UnwindPause, "UnwindPause"},
{Event::FormatDecrease, "FormatDecrease"},
{Event::FormatIncrease, "FormatIncrease"},
{Event::PaletteDecrease, "PaletteDecrease"},
{Event::PaletteIncrease, "PaletteIncrease"},
{Event::ToggleColorLoss, "ToggleColorLoss"},
{Event::PreviousPaletteAttribute, "PreviousPaletteAttribute"},
{Event::NextPaletteAttribute, "NextPaletteAttribute"},
{Event::PaletteAttributeDecrease, "PaletteAttributeDecrease"},
{Event::PaletteAttributeIncrease, "PaletteAttributeIncrease"},
{Event::ToggleFullScreen, "ToggleFullScreen"},
{Event::VidmodeDecrease, "VidmodeDecrease"},
{Event::VidmodeIncrease, "VidmodeIncrease"},
{Event::VCenterDecrease, "VCenterDecrease"},
{Event::VCenterIncrease, "VCenterIncrease"},
{Event::VSizeAdjustDecrease, "VSizeAdjustDecrease"},
{Event::VSizeAdjustIncrease, "VSizeAdjustIncrease"},
{Event::OverscanDecrease, "OverscanDecrease"},
{Event::OverscanIncrease, "OverscanIncrease"},
{Event::VidmodeStd, "VidmodeStd"},
{Event::VidmodeRGB, "VidmodeRGB"},
{Event::VidmodeSVideo, "VidmodeSVideo"},
{Event::VidModeComposite, "VidModeComposite"},
{Event::VidModeBad, "VidModeBad"},
{Event::VidModeCustom, "VidModeCustom"},
{Event::PreviousVideoMode, "PreviousVideoMode"},
{Event::NextVideoMode, "NextVideoMode"},
{Event::PreviousAttribute, "PreviousAttribute"},
{Event::NextAttribute, "NextAttribute"},
{Event::DecreaseAttribute, "DecreaseAttribute"},
{Event::IncreaseAttribute, "IncreaseAttribute"},
{Event::ScanlinesDecrease, "ScanlinesDecrease"},
{Event::ScanlinesIncrease, "ScanlinesIncrease"},
{Event::PhosphorDecrease, "PhosphorDecrease"},
{Event::PhosphorIncrease, "PhosphorIncrease"},
{Event::TogglePhosphor, "TogglePhosphor"},
{Event::ToggleInter, "ToggleInter"},
{Event::ToggleJitter, "ToggleJitter"},
{Event::VolumeDecrease, "VolumeDecrease"},
{Event::VolumeIncrease, "VolumeIncrease"},
{Event::SoundToggle, "SoundToggle"},
{Event::ToggleP0Collision, "ToggleP0Collision"},
{Event::ToggleP0Bit, "ToggleP0Bit"},
{Event::ToggleP1Collision, "ToggleP1Collision"},
{Event::ToggleP1Bit, "ToggleP1Bit"},
{Event::ToggleM0Collision, "ToggleM0Collision"},
{Event::ToggleM0Bit, "ToggleM0Bit"},
{Event::ToggleM1Collision, "ToggleM1Collision"},
{Event::ToggleM1Bit, "ToggleM1Bit"},
{Event::ToggleBLCollision, "ToggleBLCollision"},
{Event::ToggleBLBit, "ToggleBLBit"},
{Event::TogglePFCollision, "TogglePFCollision"},
{Event::TogglePFBit, "TogglePFBit"},
{Event::ToggleCollisions, "ToggleCollisions"},
{Event::ToggleBits, "ToggleBits"},
{Event::ToggleFixedColors, "ToggleFixedColors"},
{Event::ToggleFrameStats, "ToggleFrameStats"},
{Event::ToggleSAPortOrder, "ToggleSAPortOrder"},
{Event::ExitGame, "ExitGame"},
{Event::SettingDecrease, "SettingDecrease"},
{Event::SettingIncrease, "SettingIncrease"},
{Event::PreviousSetting, "PreviousSetting"},
{Event::NextSetting, "NextSetting"},
{Event::ToggleAdaptRefresh, "ToggleAdaptRefresh"},
{Event::PreviousMultiCartRom, "PreviousMultiCartRom"},
{Event::PreviousSettingGroup, "PreviousSettingGroup"},
{Event::NextSettingGroup, "NextSettingGroup"},
{Event::TogglePlayBackMode, "TogglePlayBackMode"},
{Event::DecreaseAutoFire, "DecreaseAutoFire"},
{Event::IncreaseAutoFire, "IncreaseAutoFire"},
{Event::DecreaseSpeed, "DecreaseSpeed"},
{Event::IncreaseSpeed, "IncreaseSpeed"},
{Event::JoystickTwoUp, "JoystickTwoUp"},
{Event::JoystickTwoDown, "JoystickTwoDown"},
{Event::JoystickTwoLeft, "JoystickTwoLeft"},
{Event::JoystickTwoRight, "JoystickTwoRight"},
{Event::JoystickTwoFire, "JoystickTwoFire"},
{Event::JoystickThreeUp, "JoystickThreeUp"},
{Event::JoystickThreeDown, "JoystickThreeDown"},
{Event::JoystickThreeLeft, "JoystickThreeLeft"},
{Event::JoystickThreeRight, "JoystickThreeRight"},
{Event::JoystickThreeFire, "JoystickThreeFire"},
{Event::ToggleCorrectAspectRatio, "ToggleCorrectAspectRatio"},
{Event::MoveLeftChar, "MoveLeftChar"},
{Event::MoveRightChar, "MoveRightChar"},
{Event::MoveLeftWord, "MoveLeftWord"},
{Event::MoveRightWord, "MoveRightWord"},
{Event::MoveHome, "MoveHome"},
{Event::MoveEnd, "MoveEnd"},
{Event::SelectLeftChar, "SelectLeftChar"},
{Event::SelectRightChar, "SelectRightChar"},
{Event::SelectLeftWord, "SelectLeftWord"},
{Event::SelectRightWord, "SelectRightWord"},
{Event::SelectHome, "SelectHome"},
{Event::SelectEnd, "SelectEnd"},
{Event::SelectAll, "SelectAll"},
{Event::Delete, "Delete"},
{Event::DeleteLeftWord, "DeleteLeftWord"},
{Event::DeleteRightWord, "DeleteRightWord"},
{Event::DeleteHome, "DeleteHome"},
{Event::DeleteEnd, "DeleteEnd"},
{Event::Backspace, "Backspace"},
{Event::Cut, "Cut"},
{Event::Copy, "Copy"},
{Event::Paste, "Paste"},
{Event::Undo, "Undo"},
{Event::Redo, "Redo"},
{Event::AbortEdit, "AbortEdit"},
{Event::EndEdit, "EndEdit"},
{Event::LastType, "LastType"}
})
NLOHMANN_JSON_SERIALIZE_ENUM(StellaKey, {
{StellaKey::KBDK_UNKNOWN, "unknown"},
{StellaKey::KBDK_A, "a"},
{StellaKey::KBDK_B, "b"},
{StellaKey::KBDK_C, "c"},
{StellaKey::KBDK_D, "d"},
{StellaKey::KBDK_E, "e"},
{StellaKey::KBDK_F, "f"},
{StellaKey::KBDK_G, "g"},
{StellaKey::KBDK_H, "h"},
{StellaKey::KBDK_I, "i"},
{StellaKey::KBDK_J, "j"},
{StellaKey::KBDK_K, "k"},
{StellaKey::KBDK_L, "l"},
{StellaKey::KBDK_M, "m"},
{StellaKey::KBDK_N, "n"},
{StellaKey::KBDK_O, "o"},
{StellaKey::KBDK_P, "p"},
{StellaKey::KBDK_Q, "q"},
{StellaKey::KBDK_R, "r"},
{StellaKey::KBDK_S, "s"},
{StellaKey::KBDK_T, "t"},
{StellaKey::KBDK_U, "u"},
{StellaKey::KBDK_V, "v"},
{StellaKey::KBDK_W, "w"},
{StellaKey::KBDK_X, "x"},
{StellaKey::KBDK_Y, "y"},
{StellaKey::KBDK_Z, "z"},
{StellaKey::KBDK_1, "1"},
{StellaKey::KBDK_2, "2"},
{StellaKey::KBDK_3, "3"},
{StellaKey::KBDK_4, "4"},
{StellaKey::KBDK_5, "5"},
{StellaKey::KBDK_6, "6"},
{StellaKey::KBDK_7, "7"},
{StellaKey::KBDK_8, "8"},
{StellaKey::KBDK_9, "9"},
{StellaKey::KBDK_0, "0"},
{StellaKey::KBDK_RETURN, "return"},
{StellaKey::KBDK_ESCAPE, "escape"},
{StellaKey::KBDK_BACKSPACE, "backspace"},
{StellaKey::KBDK_TAB, "tab"},
{StellaKey::KBDK_SPACE, "space"},
{StellaKey::KBDK_MINUS, "minus"},
{StellaKey::KBDK_EQUALS, "equals"},
{StellaKey::KBDK_LEFTBRACKET, "leftbracket"},
{StellaKey::KBDK_RIGHTBRACKET, "rightbracket"},
{StellaKey::KBDK_BACKSLASH, "backslash"},
{StellaKey::KBDK_NONUSHASH, "nonushash"},
{StellaKey::KBDK_SEMICOLON, "semicolon"},
{StellaKey::KBDK_APOSTROPHE, "apostrophe"},
{StellaKey::KBDK_GRAVE, "grave"},
{StellaKey::KBDK_COMMA, "comma"},
{StellaKey::KBDK_PERIOD, "period"},
{StellaKey::KBDK_SLASH, "slash"},
{StellaKey::KBDK_CAPSLOCK, "capslock"},
{StellaKey::KBDK_F1, "f1"},
{StellaKey::KBDK_F2, "f2"},
{StellaKey::KBDK_F3, "f3"},
{StellaKey::KBDK_F4, "f4"},
{StellaKey::KBDK_F5, "f5"},
{StellaKey::KBDK_F6, "f6"},
{StellaKey::KBDK_F7, "f7"},
{StellaKey::KBDK_F8, "f8"},
{StellaKey::KBDK_F9, "f9"},
{StellaKey::KBDK_F10, "f10"},
{StellaKey::KBDK_F11, "f11"},
{StellaKey::KBDK_F12, "f12"},
{StellaKey::KBDK_PRINTSCREEN, "printscreen"},
{StellaKey::KBDK_SCROLLLOCK, "scrolllock"},
{StellaKey::KBDK_PAUSE, "pause"},
{StellaKey::KBDK_INSERT, "insert"},
{StellaKey::KBDK_HOME, "home"},
{StellaKey::KBDK_PAGEUP, "pageup"},
{StellaKey::KBDK_DELETE, "delete"},
{StellaKey::KBDK_END, "end"},
{StellaKey::KBDK_PAGEDOWN, "pagedown"},
{StellaKey::KBDK_RIGHT, "right"},
{StellaKey::KBDK_LEFT, "left"},
{StellaKey::KBDK_DOWN, "down"},
{StellaKey::KBDK_UP, "up"},
{StellaKey::KBDK_NUMLOCKCLEAR, "numlockclear"},
{StellaKey::KBDK_KP_DIVIDE, "kp_divide"},
{StellaKey::KBDK_KP_MULTIPLY, "kp_multiply"},
{StellaKey::KBDK_KP_MINUS, "kp_minus"},
{StellaKey::KBDK_KP_PLUS, "kp_plus"},
{StellaKey::KBDK_KP_ENTER, "kp_enter"},
{StellaKey::KBDK_KP_1, "kp_1"},
{StellaKey::KBDK_KP_2, "kp_2"},
{StellaKey::KBDK_KP_3, "kp_3"},
{StellaKey::KBDK_KP_4, "kp_4"},
{StellaKey::KBDK_KP_5, "kp_5"},
{StellaKey::KBDK_KP_6, "kp_6"},
{StellaKey::KBDK_KP_7, "kp_7"},
{StellaKey::KBDK_KP_8, "kp_8"},
{StellaKey::KBDK_KP_9, "kp_9"},
{StellaKey::KBDK_KP_0, "kp_0"},
{StellaKey::KBDK_KP_PERIOD, "kp_period"},
{StellaKey::KBDK_NONUSBACKSLASH, "nonusbackslash"},
{StellaKey::KBDK_APPLICATION, "application"},
{StellaKey::KBDK_POWER, "power"},
{StellaKey::KBDK_KP_EQUALS, "kp_equals"},
{StellaKey::KBDK_F13, "f13"},
{StellaKey::KBDK_F14, "f14"},
{StellaKey::KBDK_F15, "f15"},
{StellaKey::KBDK_F16, "f16"},
{StellaKey::KBDK_F17, "f17"},
{StellaKey::KBDK_F18, "f18"},
{StellaKey::KBDK_F19, "f19"},
{StellaKey::KBDK_F20, "f20"},
{StellaKey::KBDK_F21, "f21"},
{StellaKey::KBDK_F22, "f22"},
{StellaKey::KBDK_F23, "f23"},
{StellaKey::KBDK_F24, "f24"},
{StellaKey::KBDK_EXECUTE, "execute"},
{StellaKey::KBDK_HELP, "help"},
{StellaKey::KBDK_MENU, "menu"},
{StellaKey::KBDK_SELECT, "select"},
{StellaKey::KBDK_STOP, "stop"},
{StellaKey::KBDK_AGAIN, "again"},
{StellaKey::KBDK_UNDO, "undo"},
{StellaKey::KBDK_CUT, "cut"},
{StellaKey::KBDK_COPY, "copy"},
{StellaKey::KBDK_PASTE, "paste"},
{StellaKey::KBDK_FIND, "find"},
{StellaKey::KBDK_MUTE, "mute"},
{StellaKey::KBDK_VOLUMEUP, "volumeup"},
{StellaKey::KBDK_VOLUMEDOWN, "volumedown"},
{StellaKey::KBDK_KP_COMMA, "kp_comma"},
{StellaKey::KBDK_KP_EQUALSAS400, "kp_equalsas400"},
{StellaKey::KBDK_INTERNATIONAL1, "international1"},
{StellaKey::KBDK_INTERNATIONAL2, "international2"},
{StellaKey::KBDK_INTERNATIONAL3, "international3"},
{StellaKey::KBDK_INTERNATIONAL4, "international4"},
{StellaKey::KBDK_INTERNATIONAL5, "international5"},
{StellaKey::KBDK_INTERNATIONAL6, "international6"},
{StellaKey::KBDK_INTERNATIONAL7, "international7"},
{StellaKey::KBDK_INTERNATIONAL8, "international8"},
{StellaKey::KBDK_INTERNATIONAL9, "international9"},
{StellaKey::KBDK_LANG1, "lang1"},
{StellaKey::KBDK_LANG2, "lang2"},
{StellaKey::KBDK_LANG3, "lang3"},
{StellaKey::KBDK_LANG4, "lang4"},
{StellaKey::KBDK_LANG5, "lang5"},
{StellaKey::KBDK_LANG6, "lang6"},
{StellaKey::KBDK_LANG7, "lang7"},
{StellaKey::KBDK_LANG8, "lang8"},
{StellaKey::KBDK_LANG9, "lang9"},
{StellaKey::KBDK_ALTERASE, "alterase"},
{StellaKey::KBDK_SYSREQ, "sysreq"},
{StellaKey::KBDK_CANCEL, "cancel"},
{StellaKey::KBDK_CLEAR, "clear"},
{StellaKey::KBDK_PRIOR, "prior"},
{StellaKey::KBDK_RETURN2, "return2"},
{StellaKey::KBDK_SEPARATOR, "separator"},
{StellaKey::KBDK_OUT, "out"},
{StellaKey::KBDK_OPER, "oper"},
{StellaKey::KBDK_CLEARAGAIN, "clearagain"},
{StellaKey::KBDK_CRSEL, "crsel"},
{StellaKey::KBDK_EXSEL, "exsel"},
{StellaKey::KBDK_KP_00, "kp_00"},
{StellaKey::KBDK_KP_000, "kp_000"},
{StellaKey::KBDK_THOUSANDSSEPARATOR, "thousandsseparator"},
{StellaKey::KBDK_DECIMALSEPARATOR, "decimalseparator"},
{StellaKey::KBDK_CURRENCYUNIT, "currencyunit"},
{StellaKey::KBDK_CURRENCYSUBUNIT, "currencysubunit"},
{StellaKey::KBDK_KP_LEFTPAREN, "kp_leftparen"},
{StellaKey::KBDK_KP_RIGHTPAREN, "kp_rightparen"},
{StellaKey::KBDK_KP_LEFTBRACE, "kp_leftbrace"},
{StellaKey::KBDK_KP_RIGHTBRACE, "kp_rightbrace"},
{StellaKey::KBDK_KP_TAB, "kp_tab"},
{StellaKey::KBDK_KP_BACKSPACE, "kp_backspace"},
{StellaKey::KBDK_KP_A, "kp_a"},
{StellaKey::KBDK_KP_B, "kp_b"},
{StellaKey::KBDK_KP_C, "kp_c"},
{StellaKey::KBDK_KP_D, "kp_d"},
{StellaKey::KBDK_KP_E, "kp_e"},
{StellaKey::KBDK_KP_F, "kp_f"},
{StellaKey::KBDK_KP_XOR, "kp_xor"},
{StellaKey::KBDK_KP_POWER, "kp_power"},
{StellaKey::KBDK_KP_PERCENT, "kp_percent"},
{StellaKey::KBDK_KP_LESS, "kp_less"},
{StellaKey::KBDK_KP_GREATER, "kp_greater"},
{StellaKey::KBDK_KP_AMPERSAND, "kp_ampersand"},
{StellaKey::KBDK_KP_DBLAMPERSAND, "kp_dblampersand"},
{StellaKey::KBDK_KP_VERTICALBAR, "kp_verticalbar"},
{StellaKey::KBDK_KP_DBLVERTICALBAR, "kp_dblverticalbar"},
{StellaKey::KBDK_KP_COLON, "kp_colon"},
{StellaKey::KBDK_KP_HASH, "kp_hash"},
{StellaKey::KBDK_KP_SPACE, "kp_space"},
{StellaKey::KBDK_KP_AT, "kp_at"},
{StellaKey::KBDK_KP_EXCLAM, "kp_exclam"},
{StellaKey::KBDK_KP_MEMSTORE, "kp_memstore"},
{StellaKey::KBDK_KP_MEMRECALL, "kp_memrecall"},
{StellaKey::KBDK_KP_MEMCLEAR, "kp_memclear"},
{StellaKey::KBDK_KP_MEMADD, "kp_memadd"},
{StellaKey::KBDK_KP_MEMSUBTRACT, "kp_memsubtract"},
{StellaKey::KBDK_KP_MEMMULTIPLY, "kp_memmultiply"},
{StellaKey::KBDK_KP_MEMDIVIDE, "kp_memdivide"},
{StellaKey::KBDK_KP_PLUSMINUS, "kp_plusminus"},
{StellaKey::KBDK_KP_CLEAR, "kp_clear"},
{StellaKey::KBDK_KP_CLEARENTRY, "kp_clearentry"},
{StellaKey::KBDK_KP_BINARY, "kp_binary"},
{StellaKey::KBDK_KP_OCTAL, "kp_octal"},
{StellaKey::KBDK_KP_DECIMAL, "kp_decimal"},
{StellaKey::KBDK_KP_HEXADECIMAL, "kp_hexadecimal"},
{StellaKey::KBDK_LCTRL, "lctrl"},
{StellaKey::KBDK_LSHIFT, "lshift"},
{StellaKey::KBDK_LALT, "lalt"},
{StellaKey::KBDK_LGUI, "lgui"},
{StellaKey::KBDK_RCTRL, "rctrl"},
{StellaKey::KBDK_RSHIFT, "rshift"},
{StellaKey::KBDK_RALT, "ralt"},
{StellaKey::KBDK_RGUI, "rgui"},
{StellaKey::KBDK_MODE, "mode"},
{StellaKey::KBDK_AUDIONEXT, "audionext"},
{StellaKey::KBDK_AUDIOPREV, "audioprev"},
{StellaKey::KBDK_AUDIOSTOP, "audiostop"},
{StellaKey::KBDK_AUDIOPLAY, "audioplay"},
{StellaKey::KBDK_AUDIOMUTE, "audiomute"},
{StellaKey::KBDK_MEDIASELECT, "mediaselect"},
{StellaKey::KBDK_WWW, "www"},
{StellaKey::KBDK_MAIL, "mail"},
{StellaKey::KBDK_CALCULATOR, "calculator"},
{StellaKey::KBDK_COMPUTER, "computer"},
{StellaKey::KBDK_AC_SEARCH, "ac_search"},
{StellaKey::KBDK_AC_HOME, "ac_home"},
{StellaKey::KBDK_AC_BACK, "ac_back"},
{StellaKey::KBDK_AC_FORWARD, "ac_forward"},
{StellaKey::KBDK_AC_STOP, "ac_stop"},
{StellaKey::KBDK_AC_REFRESH, "ac_refresh"},
{StellaKey::KBDK_AC_BOOKMARKS, "ac_bookmarks"},
{StellaKey::KBDK_BRIGHTNESSDOWN, "brightnessdown"},
{StellaKey::KBDK_BRIGHTNESSUP, "brightnessup"},
{StellaKey::KBDK_DISPLAYSWITCH, "displayswitch"},
{StellaKey::KBDK_KBDILLUMTOGGLE, "kbdillumtoggle"},
{StellaKey::KBDK_KBDILLUMDOWN, "kbdillumdown"},
{StellaKey::KBDK_KBDILLUMUP, "kbdillumup"},
{StellaKey::KBDK_EJECT, "eject"},
{StellaKey::KBDK_SLEEP, "sleep"},
{StellaKey::KBDK_APP1, "app1"},
{StellaKey::KBDK_APP2, "app2"},
{StellaKey::KBDK_LAST, "last"}
})
NLOHMANN_JSON_SERIALIZE_ENUM(StellaMod, {
{StellaMod::KBDM_NONE, "none"},
{StellaMod::KBDM_LSHIFT, "lshift"},
{StellaMod::KBDM_RSHIFT, "rshift"},
{StellaMod::KBDM_LCTRL, "lctrl"},
{StellaMod::KBDM_RCTRL, "rctrl"},
{StellaMod::KBDM_LALT, "lalt"},
{StellaMod::KBDM_RALT, "ralt"},
{StellaMod::KBDM_LGUI, "lgui"},
{StellaMod::KBDM_RGUI, "rgui"},
{StellaMod::KBDM_NUM, "num"},
{StellaMod::KBDM_CAPS, "caps"},
{StellaMod::KBDM_MODE, "mode"},
{StellaMod::KBDM_RESERVED, "reserved"},
{StellaMod::KBDM_CTRL, "ctrl"},
{StellaMod::KBDM_SHIFT, "shift"},
{StellaMod::KBDM_ALT, "alt"},
{StellaMod::KBDM_GUI, "gui"}
})
#endif // JSON_DEFINITIONS_HXX

View File

@ -123,13 +123,12 @@ void ToolTip::release(bool emptyTip)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ToolTip::show(const string& tip)
{
uInt32 maxRows = MAX_ROWS;
myTipPos = myMousePos;
uInt32 maxWidth = std::min(myWidth - myTextXOfs * 2, uInt32(myFont->getStringWidth(tip)));
mySurface->fillRect(1, 1, maxWidth + myTextXOfs * 2 - 2, myHeight - 2, kWidColor);
int lines = std::min(maxRows,
int lines = std::min(MAX_ROWS,
uInt32(mySurface->drawString(*myFont, tip, myTextXOfs, myTextYOfs,
maxWidth, myHeight - myTextYOfs * 2,
kTextColor)));

21
src/json/LICENSE.MIT Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-2020 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1633
src/json/README.md Normal file

File diff suppressed because it is too large Load Diff

25447
src/json/json.hxx Normal file

File diff suppressed because it is too large Load Diff