Replace unmaintained cpptoml with toml++

This commit is contained in:
James Benton 2022-01-23 15:42:05 +00:00
parent 1b94896a21
commit f0276954be
16 changed files with 429 additions and 447 deletions

6
.gitmodules vendored
View file

@ -31,9 +31,6 @@
[submodule "libraries/catch"]
path = libraries/catch
url = https://github.com/philsquared/Catch.git
[submodule "libraries/cpptoml"]
path = libraries/cpptoml
url = https://github.com/decaf-emu/cpptoml.git
[submodule "libraries/cpp-peglib"]
path = libraries/cpp-peglib
url = https://github.com/yhirose/cpp-peglib.git
@ -46,3 +43,6 @@
[submodule "libraries/qtads"]
path = libraries/qtads
url = https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
[submodule "libraries/tomlplusplus"]
path = libraries/tomlplusplus
url = https://github.com/marzer/tomlplusplus.git

View file

@ -31,12 +31,6 @@ add_library(cnl INTERFACE IMPORTED GLOBAL)
set_target_properties(cnl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/cnl/include")
# cpptoml
add_library(cpptoml INTERFACE IMPORTED GLOBAL)
set_target_properties(cpptoml PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "CPPTOML_USE_MAP"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/cpptoml/include")
# excmd
add_library(excmd INTERFACE IMPORTED GLOBAL)
set_target_properties(excmd PROPERTIES
@ -94,6 +88,11 @@ set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "Use external fmt library instead of bundl
add_subdirectory(spdlog)
set_target_properties(spdlog PROPERTIES FOLDER libraries)
# tomlplusplus
add_library(tomlplusplus INTERFACE IMPORTED GLOBAL)
set_target_properties(tomlplusplus PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/tomlplusplus/include")
# Qt Advanced Docking System
if(DECAF_QT)
set(BUILD_STATIC TRUE CACHE BOOL "ADS: Build the static library")

@ -1 +0,0 @@
Subproject commit 5a6d92731aa8c2d1b2eb2741b1ea982967f77029

@ -0,0 +1 @@
Subproject commit 8e669aa6990e0ed219c169d491472d749f54c393

View file

@ -11,22 +11,17 @@ int timeout_ms = 0;
} // namespace system
bool
loadFrontendToml(std::shared_ptr<cpptoml::table> config)
loadFrontendToml(const toml::table &config)
{
system::timeout_ms = config->get_qualified_as<int>("system.timeout_ms").value_or(system::timeout_ms);
readValue(config, "system.timeout_ms", system::timeout_ms);
return true;
}
bool
saveFrontendToml(std::shared_ptr<cpptoml::table> config)
saveFrontendToml(toml::table &config)
{
auto system = config->get_table("system");
if (!system) {
system = cpptoml::make_table();
}
auto system = config.insert("system", toml::table()).first->second.as_table();
system->insert("timeout_ms", system::timeout_ms);
config->insert("system", system);
return true;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <libconfig/config_toml.h>
#include <string>
#include <toml++/toml.h>
namespace config
{
@ -13,9 +14,9 @@ extern int timeout_ms;
} // namespace system
bool
loadFrontendToml(std::shared_ptr<cpptoml::table> config);
loadFrontendToml(const toml::table &config);
bool
saveFrontendToml(std::shared_ptr<cpptoml::table> config);
saveFrontendToml(toml::table &config);
} // namespace config

View file

@ -11,6 +11,7 @@
#include <libdecaf/decaf.h>
#include <libdecaf/decaf_log.h>
#include <spdlog/sinks/stdout_sinks.h>
#include <toml++/toml.h>
std::shared_ptr<spdlog::logger>
gCliLog;
@ -115,22 +116,22 @@ start(excmd::parser &parser,
// If config file does not exist, create a default one.
if (!platform::fileExists(configPath)) {
auto toml = cpptoml::make_table();
auto toml = toml::table();
config::saveToTOML(toml, cpuSettings);
config::saveToTOML(toml, gpuSettings);
config::saveToTOML(toml, decafSettings);
config::saveFrontendToml(toml);
std::ofstream out { configPath };
out << (*toml);
out << toml;
}
try {
auto toml = cpptoml::parse_file(configPath);
auto toml = toml::parse_file(configPath);
config::loadFromTOML(toml, cpuSettings);
config::loadFromTOML(toml, gpuSettings);
config::loadFromTOML(toml, decafSettings);
config::loadFrontendToml(toml);
} catch (cpptoml::parse_exception ex) {
} catch (const toml::parse_error &ex) {
configError = ex.what();
}

View file

@ -7,7 +7,6 @@
#include <array>
#include <libdecaf/decaf_input.h>
#include <mutex>
#include <cpptoml.h>
class QKeyEvent;
class SettingsStorage;

View file

@ -3,20 +3,21 @@
#include <libconfig/config_toml.h>
#include <optional>
#include <toml++/toml.h>
static bool loadFromTOML(std::shared_ptr<cpptoml::table> config,
static bool loadFromTOML(const toml::table &config,
InputConfiguration &inputConfiguration);
static bool saveToTOML(std::shared_ptr<cpptoml::table> config,
static bool saveToTOML(toml::table &config,
const InputConfiguration &inputConfiguration);
static bool loadFromTOML(std::shared_ptr<cpptoml::table> config,
static bool loadFromTOML(const toml::table &config,
SoundSettings &soundSettings);
static bool saveToTOML(std::shared_ptr<cpptoml::table> config,
static bool saveToTOML(toml::table &config,
const SoundSettings &soundSettings);
static bool loadFromTOML(std::shared_ptr<cpptoml::table> config,
static bool loadFromTOML(const toml::table &config,
UiSettings &uiSettings);
static bool saveToTOML(std::shared_ptr<cpptoml::table> config,
static bool saveToTOML(toml::table &config,
const UiSettings &uiSettings);
bool
@ -24,7 +25,7 @@ loadSettings(const std::string &path,
Settings &settings)
{
try {
auto toml = cpptoml::parse_file(path);
toml::table toml = toml::parse_file(path);
config::loadFromTOML(toml, settings.cpu);
config::loadFromTOML(toml, settings.decaf);
config::loadFromTOML(toml, settings.gpu);
@ -32,7 +33,7 @@ loadSettings(const std::string &path,
loadFromTOML(toml, settings.sound);
loadFromTOML(toml, settings.ui);
return true;
} catch (cpptoml::parse_exception ex) {
} catch (const toml::parse_error &) {
return false;
}
}
@ -41,12 +42,11 @@ bool
saveSettings(const std::string &path,
const Settings &settings)
{
auto toml = std::shared_ptr<cpptoml::table> { };
toml::table toml;
try {
// Read current file and modify that
toml = cpptoml::parse_file(path);
} catch (cpptoml::parse_exception ex) {
toml = cpptoml::make_table();
toml = toml::parse_file(path);
} catch (const toml::parse_error &) {
}
// Update it
@ -63,7 +63,7 @@ saveSettings(const std::string &path,
return false;
}
out << (*toml);
out << toml;
return true;
}
@ -129,105 +129,111 @@ getConfigButtonName(ButtonType type)
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
InputConfiguration &inputConfiguration)
{
auto controllers = config->get_table_array_qualified("input.controller");
auto controllers = config.at_path("input.controller").as_array();
if (!controllers) {
return true;
}
if (controllers) {
for (const auto &controllerConfig : *controllers) {
auto controllerType = controllerConfig->get_as<std::string>("type").value_or("");
auto &controller = inputConfiguration.controllers.emplace_back();
for (const auto &controllerConfig : *controllers) {
auto controllerConfigTable = controllerConfig.as_table();
if (!controllerConfigTable) {
continue;
}
auto &controller = inputConfiguration.controllers.emplace_back();
if (controllerType == "gamepad") {
controller.type = ControllerType::Gamepad;
} else if (controllerType == "wiimote") {
controller.type = ControllerType::WiiMote;
} else if (controllerType == "pro") {
controller.type = ControllerType::ProController;
} else if (controllerType == "classic") {
controller.type = ControllerType::ClassicController;
} else {
continue;
}
auto controllerType = controllerConfigTable->get_as<std::string>("type");
if (!controllerType) {
continue;
} else if (**controllerType == "gamepad") {
controller.type = ControllerType::Gamepad;
} else if (**controllerType == "wiimote") {
controller.type = ControllerType::WiiMote;
} else if (**controllerType == "pro") {
controller.type = ControllerType::ProController;
} else if (**controllerType == "classic") {
controller.type = ControllerType::ClassicController;
} else {
continue;
}
auto readInputConfig = [](std::shared_ptr<cpptoml::table> controllerConfig, InputConfiguration::Controller &controller, ButtonType buttonType)
auto readInputConfig =
[](const toml::table &controllerConfig,
InputConfiguration::Controller &controller,
ButtonType buttonType)
{
auto &input = controller.inputs[static_cast<size_t>(buttonType)];
auto buttonConfig = controllerConfig->get_table(getConfigButtonName(buttonType));
auto buttonConfig = controllerConfig.get_as<toml::table>(getConfigButtonName(buttonType));
if (buttonConfig) {
if (auto guid = buttonConfig->get_as<std::string>("sdl_joystick_guid"); guid) {
input.joystickGuid = SDL_JoystickGetGUIDFromString(guid->c_str());
input.joystickGuid = SDL_JoystickGetGUIDFromString(guid->get().c_str());
}
if (auto id = buttonConfig->get_as<int>("sdl_joystick_duplicate_id"); id) {
input.joystickDuplicateId = *id;
if (auto id = buttonConfig->get_as<int64_t>("sdl_joystick_duplicate_id"); id) {
input.joystickDuplicateId = id->get();
}
if (auto key = buttonConfig->get_as<int>("key"); key) {
if (auto key = buttonConfig->get_as<int64_t>("key"); key) {
input.source = InputConfiguration::Input::KeyboardKey;
input.id = *key;
input.id = key->get();
}
if (auto button = buttonConfig->get_as<int>("button"); button) {
if (auto button = buttonConfig->get_as<int64_t>("button"); button) {
input.source = InputConfiguration::Input::JoystickButton;
input.id = *button;
input.id = button->get();
}
if (auto axis = buttonConfig->get_as<int>("axis"); axis) {
if (auto axis = buttonConfig->get_as<int64_t>("axis"); axis) {
input.source = InputConfiguration::Input::JoystickAxis;
input.id = *axis;
input.id = axis->get();
}
if (auto hat = buttonConfig->get_as<int>("hat"); hat) {
if (auto hat = buttonConfig->get_as<int64_t>("hat"); hat) {
input.source = InputConfiguration::Input::JoystickHat;
input.id = *hat;
input.id = hat->get();
input.hatValue = 0;
}
if (auto hatValue = buttonConfig->get_as<int>("hat_value"); hatValue) {
input.hatValue = *hatValue;
if (auto hatValue = buttonConfig->get_as<int64_t>("hat_value"); hatValue) {
input.hatValue = hatValue->get();
}
if (auto invert = buttonConfig->get_as<bool>("invert"); invert) {
input.invert = *invert;
input.invert = invert->get();
}
}
};
for (auto i = 0u; i < static_cast<size_t>(ButtonType::MaxButtonType); ++i) {
readInputConfig(controllerConfig, controller, static_cast<ButtonType>(i));
}
for (auto i = 0u; i < static_cast<size_t>(ButtonType::MaxButtonType); ++i) {
readInputConfig(*controllerConfigTable, controller, static_cast<ButtonType>(i));
}
}
return true;
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const InputConfiguration &inputConfiguration)
{
auto input = config->get_table("input");
if (!input) {
input = cpptoml::make_table();
}
auto input = config.insert("input", toml::table()).first->second.as_table();
auto controllers = cpptoml::make_table_array();
if (input->get_table_array("controller")) {
auto controllers = toml::array();
if (input->contains("controller")) {
input->erase("controller");
}
for (auto &controller : inputConfiguration.controllers) {
auto controllerConfig = cpptoml::make_table();
auto controllerConfig = toml::table();
if (controller.type == ControllerType::Gamepad) {
controllerConfig->insert("type", "gamepad");
controllerConfig.insert("type", "gamepad");
} else if (controller.type == ControllerType::WiiMote) {
controllerConfig->insert("type", "wiimote");
controllerConfig.insert("type", "wiimote");
} else if (controller.type == ControllerType::ProController) {
controllerConfig->insert("type", "pro");
controllerConfig.insert("type", "pro");
} else if (controller.type == ControllerType::ClassicController) {
controllerConfig->insert("type", "classic");
controllerConfig.insert("type", "classic");
} else {
continue;
}
@ -235,68 +241,57 @@ saveToTOML(std::shared_ptr<cpptoml::table> config,
for (auto i = 0u; i < static_cast<size_t>(ButtonType::MaxButtonType); ++i) {
auto buttonType = static_cast<ButtonType>(i);
auto &input = controller.inputs[i];
auto inputConfig = cpptoml::make_table();
auto inputConfig = toml::table();
if (input.source == InputConfiguration::Input::Unassigned) {
continue;
} else if (input.source == InputConfiguration::Input::KeyboardKey) {
inputConfig->insert("key", input.id);
inputConfig.insert("key", input.id);
} else if (input.source == InputConfiguration::Input::JoystickAxis) {
char guidBuffer[33];
SDL_JoystickGetGUIDString(input.joystickGuid, guidBuffer, 33);
inputConfig->insert("sdl_joystick_guid", guidBuffer);
inputConfig->insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig->insert("axis", input.id);
inputConfig->insert("invert", input.invert);
inputConfig.insert("sdl_joystick_guid", guidBuffer);
inputConfig.insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig.insert("axis", input.id);
inputConfig.insert("invert", input.invert);
} else if (input.source == InputConfiguration::Input::JoystickButton) {
char guidBuffer[33];
SDL_JoystickGetGUIDString(input.joystickGuid, guidBuffer, 33);
inputConfig->insert("sdl_joystick_guid", guidBuffer);
inputConfig->insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig->insert("button", input.id);
inputConfig.insert("sdl_joystick_guid", guidBuffer);
inputConfig.insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig.insert("button", input.id);
} else if (input.source == InputConfiguration::Input::JoystickHat) {
char guidBuffer[33];
SDL_JoystickGetGUIDString(input.joystickGuid, guidBuffer, 33);
inputConfig->insert("sdl_joystick_guid", guidBuffer);
inputConfig->insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig->insert("hat", input.id);
inputConfig->insert("hat_value", input.hatValue);
inputConfig.insert("sdl_joystick_guid", guidBuffer);
inputConfig.insert("sdl_joystick_duplicate_id", input.joystickDuplicateId);
inputConfig.insert("hat", input.id);
inputConfig.insert("hat_value", input.hatValue);
}
controllerConfig->insert(getConfigButtonName(buttonType), inputConfig);
controllerConfig.insert(getConfigButtonName(buttonType), inputConfig);
}
controllers->push_back(controllerConfig);
controllers.push_back(std::move(controllerConfig));
}
input->insert("controller", controllers);
config->insert("input", input);
input->insert("controller", std::move(controllers));
return true;
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
SoundSettings &soundSettings)
{
if (auto sound = config->get_table("sound")) {
if (auto playbackEnabled = sound->get_as<bool>("playback_enabled"); playbackEnabled) {
soundSettings.playbackEnabled = *playbackEnabled;
}
}
config::readValue(config, "sound.playback_enabled", soundSettings.playbackEnabled);
return true;
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const SoundSettings &soundSettings)
{
auto sound = config->get_table("sound");
if (!sound) {
sound = cpptoml::make_table();
}
auto sound = config.insert("sound", toml::table()).first->second.as_table();
sound->insert("playback_enabled", soundSettings.playbackEnabled);
config->insert("sound", sound);
return true;
}
@ -326,33 +321,27 @@ translateTitleListMode(const std::string &text)
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
UiSettings &uiSettings)
{
if (auto ui = config->get_table("ui")) {
if (auto text = ui->get_as<std::string>("title_list_mode"); text) {
if (auto mode = translateTitleListMode(*text); mode) {
uiSettings.titleListMode = *mode;
}
}
std::string titleListModeText;
config::readValue(config, "ui.title_list_mode", titleListModeText);
if (auto mode = translateTitleListMode(titleListModeText); mode) {
uiSettings.titleListMode = *mode;
}
return true;
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const UiSettings &uiSettings)
{
auto ui = config->get_table("ui");
if (!ui) {
ui = cpptoml::make_table();
}
auto ui = config.insert("ui", toml::table()).first->second.as_table();
if (auto text = translateTitleListMode(uiSettings.titleListMode); text) {
ui->insert("title_list_mode", text);
}
config->insert("ui", ui);
return true;
}

View file

@ -78,14 +78,18 @@ setupDefaultInputDevices()
device.button_minus = SDL_SCANCODE_2;
device.button_home = SDL_SCANCODE_3;
device.button_sync = SDL_SCANCODE_4;
device.keyboard.left_stick_up = SDL_SCANCODE_KP_8;
device.keyboard.left_stick_down = SDL_SCANCODE_KP_2;
device.keyboard.left_stick_left = SDL_SCANCODE_KP_4;
device.keyboard.left_stick_right = SDL_SCANCODE_KP_6;
device.keyboard.right_stick_up = -1;
device.keyboard.right_stick_down = -1;
device.keyboard.right_stick_left = -1;
device.keyboard.right_stick_right = -1;
input::InputDeviceKeyboard keyboard;
keyboard.left_stick_up = SDL_SCANCODE_KP_8;
keyboard.left_stick_down = SDL_SCANCODE_KP_2;
keyboard.left_stick_left = SDL_SCANCODE_KP_4;
keyboard.left_stick_right = SDL_SCANCODE_KP_6;
keyboard.right_stick_up = -1;
keyboard.right_stick_down = -1;
keyboard.right_stick_left = -1;
keyboard.right_stick_right = -1;
device.typeExtra = keyboard;
input::devices.push_back(device);
}
@ -113,195 +117,191 @@ setupDefaultInputDevices()
device.button_minus = -2;
device.button_home = -2;
device.button_sync = -2;
device.joystick.left_stick_x = -2;
device.joystick.left_stick_x_invert = false;
device.joystick.left_stick_y = -2;
device.joystick.left_stick_y_invert = false;
device.joystick.right_stick_x = -2;
device.joystick.right_stick_x_invert = false;
device.joystick.right_stick_y = -2;
device.joystick.right_stick_y_invert = false;
input::InputDeviceJoystick joystick;
joystick.left_stick_x = -2;
joystick.left_stick_x_invert = false;
joystick.left_stick_y = -2;
joystick.left_stick_y_invert = false;
joystick.right_stick_x = -2;
joystick.right_stick_x_invert = false;
joystick.right_stick_y = -2;
joystick.right_stick_y_invert = false;
device.typeExtra = joystick;
input::devices.push_back(device);
}
}
bool
loadFrontendToml(std::shared_ptr<cpptoml::table> config)
loadFrontendToml(const toml::table &config)
{
// input
auto devices = config->get_table_array_qualified("input.devices");
auto devices = config.at_path("input.devices").as_array();
input::devices.clear();
if (devices) {
for (const auto &cfgDevice : *devices) {
for (auto itr = devices->begin(); itr != devices->end(); ++itr) {
auto cfgDevice = itr->as_table();
config::input::InputDevice device;
auto type = cfgDevice->get_as<std::string>("type").value_or("");
if (type == "keyboard") {
auto type = cfgDevice->get_as<std::string>("type");
if (!type) {
continue;
} else if (type->get() == "keyboard") {
device.type = config::input::ControllerType::Keyboard;
} else if (type == "joystick") {
} else if (type->get() == "joystick") {
device.type = config::input::ControllerType::Joystick;
} else {
continue;
}
device.id = cfgDevice->get_as<std::string>("id").value_or("");
device.device_name = cfgDevice->get_as<std::string>("device_name").value_or("");
device.button_up = cfgDevice->get_as<int>("button_up").value_or(-1);
device.button_down = cfgDevice->get_as<int>("button_down").value_or(-1);
device.button_left = cfgDevice->get_as<int>("button_left").value_or(-1);
device.button_right = cfgDevice->get_as<int>("button_right").value_or(-1);
device.button_a = cfgDevice->get_as<int>("button_a").value_or(-1);
device.button_b = cfgDevice->get_as<int>("button_b").value_or(-1);
device.button_x = cfgDevice->get_as<int>("button_x").value_or(-1);
device.button_y = cfgDevice->get_as<int>("button_y").value_or(-1);
device.button_trigger_r = cfgDevice->get_as<int>("button_trigger_r").value_or(-1);
device.button_trigger_l = cfgDevice->get_as<int>("button_trigger_l").value_or(-1);
device.button_trigger_zr = cfgDevice->get_as<int>("button_trigger_zr").value_or(-1);
device.button_trigger_zl = cfgDevice->get_as<int>("button_trigger_zl").value_or(-1);
device.button_stick_l = cfgDevice->get_as<int>("button_stick_l").value_or(-1);
device.button_stick_r = cfgDevice->get_as<int>("button_stick_r").value_or(-1);
device.button_plus = cfgDevice->get_as<int>("button_plus").value_or(-1);
device.button_minus = cfgDevice->get_as<int>("button_minus").value_or(-1);
device.button_home = cfgDevice->get_as<int>("button_home").value_or(-1);
device.button_sync = cfgDevice->get_as<int>("button_sync").value_or(-1);
readValue(*cfgDevice, "id", device.id);
readValue(*cfgDevice, "device_name", device.device_name);
readValue(*cfgDevice, "button_up", device.button_up);
readValue(*cfgDevice, "button_down", device.button_down);
readValue(*cfgDevice, "button_left", device.button_left);
readValue(*cfgDevice, "button_right", device.button_right);
readValue(*cfgDevice, "button_a", device.button_a);
readValue(*cfgDevice, "button_b", device.button_b);
readValue(*cfgDevice, "button_x", device.button_x);
readValue(*cfgDevice, "button_y", device.button_y);
readValue(*cfgDevice, "button_trigger_r", device.button_trigger_r);
readValue(*cfgDevice, "button_trigger_l", device.button_trigger_l);
readValue(*cfgDevice, "button_trigger_zr", device.button_trigger_zr);
readValue(*cfgDevice, "button_trigger_zl", device.button_trigger_zl);
readValue(*cfgDevice, "button_stick_l", device.button_stick_l);
readValue(*cfgDevice, "button_stick_r", device.button_stick_r);
readValue(*cfgDevice, "button_plus", device.button_plus);
readValue(*cfgDevice, "button_minus", device.button_minus);
readValue(*cfgDevice, "button_home", device.button_home);
readValue(*cfgDevice, "button_sync", device.button_sync);
if (device.type == config::input::ControllerType::Keyboard) {
device.keyboard.left_stick_up = cfgDevice->get_as<int>("left_stick_up").value_or(-1);
device.keyboard.left_stick_down = cfgDevice->get_as<int>("left_stick_down").value_or(-1);
device.keyboard.left_stick_left = cfgDevice->get_as<int>("left_stick_left").value_or(-1);
device.keyboard.left_stick_right = cfgDevice->get_as<int>("left_stick_right").value_or(-1);
device.keyboard.right_stick_up = cfgDevice->get_as<int>("right_stick_up").value_or(-1);
device.keyboard.right_stick_down = cfgDevice->get_as<int>("right_stick_down").value_or(-1);
device.keyboard.right_stick_left = cfgDevice->get_as<int>("right_stick_left").value_or(-1);
device.keyboard.right_stick_right = cfgDevice->get_as<int>("right_stick_right").value_or(-1);
auto keyboard = config::input::InputDeviceKeyboard {};
readValue(*cfgDevice, "left_stick_up", keyboard.left_stick_up);
readValue(*cfgDevice, "left_stick_down", keyboard.left_stick_down);
readValue(*cfgDevice, "left_stick_left", keyboard.left_stick_left);
readValue(*cfgDevice, "left_stick_right", keyboard.left_stick_right);
readValue(*cfgDevice, "right_stick_up", keyboard.right_stick_up);
readValue(*cfgDevice, "right_stick_down", keyboard.right_stick_down);
readValue(*cfgDevice, "right_stick_left", keyboard.right_stick_left);
readValue(*cfgDevice, "right_stick_right", keyboard.right_stick_right);
device.typeExtra = keyboard;
} else if (device.type == config::input::ControllerType::Joystick) {
device.joystick.left_stick_x = cfgDevice->get_as<int>("left_stick_x").value_or(-1);
device.joystick.left_stick_x_invert = cfgDevice->get_as<bool>("left_stick_x_invert").value_or(false);
device.joystick.left_stick_y = cfgDevice->get_as<int>("left_stick_y").value_or(-1);
device.joystick.left_stick_y_invert = cfgDevice->get_as<bool>("left_stick_y_invert").value_or(false);
device.joystick.right_stick_x = cfgDevice->get_as<int>("right_stick_x").value_or(-1);
device.joystick.right_stick_x_invert = cfgDevice->get_as<bool>("right_stick_x_invert").value_or(false);
device.joystick.right_stick_y = cfgDevice->get_as<int>("right_stick_y").value_or(-1);
device.joystick.right_stick_y_invert = cfgDevice->get_as<bool>("right_stick_y_invert").value_or(false);
auto joystick = config::input::InputDeviceJoystick {};
readValue(*cfgDevice, "left_stick_x", joystick.left_stick_x);
readValue(*cfgDevice, "left_stick_x_invert", joystick.left_stick_x_invert);
readValue(*cfgDevice, "left_stick_y", joystick.left_stick_y);
readValue(*cfgDevice, "left_stick_y_invert", joystick.left_stick_y_invert);
readValue(*cfgDevice, "right_stick_x", joystick.right_stick_x);
readValue(*cfgDevice, "right_stick_x_invert", joystick.right_stick_x_invert);
readValue(*cfgDevice, "right_stick_y", joystick.right_stick_y);
readValue(*cfgDevice, "right_stick_y_invert", joystick.right_stick_y_invert);
device.typeExtra = joystick;
}
config::input::devices.push_back(device);
}
}
config::input::vpad0 = config->get_qualified_as<std::string>("input.vpad0").value_or(config::input::vpad0);
readValue(config, "input.vpad0", config::input::vpad0);
setupDefaultInputDevices();
// sound
config::sound::frame_length = config->get_qualified_as<unsigned int>("sound.frame_length").value_or(config::sound::frame_length);
readValue(config, "sound.frame_length", config::sound::frame_length);
// test
config::test::timeout_ms = config->get_qualified_as<int>("test.timeout_ms").value_or(config::test::timeout_ms);
config::test::timeout_frames = config->get_qualified_as<int>("test.timeout_frames").value_or(config::test::timeout_frames);
config::test::dump_drc_frames = config->get_qualified_as<bool>("test.dump_drc_frames").value_or(config::test::dump_drc_frames);
config::test::dump_tv_frames = config->get_qualified_as<bool>("test.dump_tv_frames").value_or(config::test::dump_tv_frames);
config::test::dump_frames_dir = config->get_qualified_as<std::string>("test.dump_frames_dir").value_or(config::test::dump_frames_dir);
readValue(config, "test.timeout_ms", config::test::timeout_ms);
readValue(config, "test.timeout_frames", config::test::timeout_frames);
readValue(config, "test.dump_drc_frames", config::test::dump_drc_frames);
readValue(config, "test.dump_tv_frames", config::test::dump_tv_frames);
readValue(config, "test.dump_frames_dir", config::test::dump_frames_dir);
return true;
}
bool
saveFrontendToml(std::shared_ptr<cpptoml::table> config)
saveFrontendToml(toml::table &config)
{
setupDefaultInputDevices();
// input
auto input = config->get_table("input");
if (!input) {
input = cpptoml::make_table();
}
auto input = config.insert("input", toml::table()).first->second.as_table();
input->insert("vpad0", config::input::vpad0);
auto devices = config->get_table_array("devices");
if (!devices) {
devices = cpptoml::make_table_array();
}
auto devices = config.insert("devices", toml::array()).first->second.as_array();
for (const auto &device : config::input::devices) {
auto cfgDevice = cpptoml::make_table();
auto cfgDevice = toml::table();
if (device.type == config::input::ControllerType::Joystick) {
cfgDevice->insert("type", "joystick");
cfgDevice.insert("type", "joystick");
} else if (device.type == config::input::ControllerType::Keyboard) {
cfgDevice->insert("type", "keyboard");
cfgDevice.insert("type", "keyboard");
} else {
cfgDevice->insert("type", "unknown");
cfgDevice.insert("type", "unknown");
}
cfgDevice->insert("id", device.id);
cfgDevice->insert("device_name", device.device_name);
cfgDevice->insert("button_up", device.button_up);
cfgDevice->insert("button_down", device.button_down);
cfgDevice->insert("button_left", device.button_left);
cfgDevice->insert("button_right", device.button_right);
cfgDevice->insert("button_a", device.button_a);
cfgDevice->insert("button_b", device.button_b);
cfgDevice->insert("button_x", device.button_x);
cfgDevice->insert("button_y", device.button_y);
cfgDevice->insert("button_trigger_r", device.button_trigger_r);
cfgDevice->insert("button_trigger_l", device.button_trigger_l);
cfgDevice->insert("button_trigger_zr", device.button_trigger_zr);
cfgDevice->insert("button_trigger_zl", device.button_trigger_zl);
cfgDevice->insert("button_stick_l", device.button_stick_l);
cfgDevice->insert("button_stick_r", device.button_stick_r);
cfgDevice->insert("button_plus", device.button_plus);
cfgDevice->insert("button_minus", device.button_minus);
cfgDevice->insert("button_home", device.button_home);
cfgDevice->insert("button_sync", device.button_sync);
cfgDevice.insert("id", device.id);
cfgDevice.insert("device_name", device.device_name);
cfgDevice.insert("button_up", device.button_up);
cfgDevice.insert("button_down", device.button_down);
cfgDevice.insert("button_left", device.button_left);
cfgDevice.insert("button_right", device.button_right);
cfgDevice.insert("button_a", device.button_a);
cfgDevice.insert("button_b", device.button_b);
cfgDevice.insert("button_x", device.button_x);
cfgDevice.insert("button_y", device.button_y);
cfgDevice.insert("button_trigger_r", device.button_trigger_r);
cfgDevice.insert("button_trigger_l", device.button_trigger_l);
cfgDevice.insert("button_trigger_zr", device.button_trigger_zr);
cfgDevice.insert("button_trigger_zl", device.button_trigger_zl);
cfgDevice.insert("button_stick_l", device.button_stick_l);
cfgDevice.insert("button_stick_r", device.button_stick_r);
cfgDevice.insert("button_plus", device.button_plus);
cfgDevice.insert("button_minus", device.button_minus);
cfgDevice.insert("button_home", device.button_home);
cfgDevice.insert("button_sync", device.button_sync);
if (device.type == config::input::ControllerType::Keyboard) {
cfgDevice->insert("left_stick_up", device.keyboard.left_stick_up);
cfgDevice->insert("left_stick_down", device.keyboard.left_stick_down);
cfgDevice->insert("left_stick_left", device.keyboard.left_stick_left);
cfgDevice->insert("left_stick_right", device.keyboard.left_stick_right);
cfgDevice->insert("right_stick_up", device.keyboard.right_stick_up);
cfgDevice->insert("right_stick_down", device.keyboard.right_stick_down);
cfgDevice->insert("right_stick_left", device.keyboard.right_stick_left);
cfgDevice->insert("right_stick_right", device.keyboard.right_stick_right);
const auto &keyboard =
std::get<config::input::InputDeviceKeyboard>(device.typeExtra);
cfgDevice.insert("left_stick_up", keyboard.left_stick_up);
cfgDevice.insert("left_stick_down", keyboard.left_stick_down);
cfgDevice.insert("left_stick_left", keyboard.left_stick_left);
cfgDevice.insert("left_stick_right", keyboard.left_stick_right);
cfgDevice.insert("right_stick_up", keyboard.right_stick_up);
cfgDevice.insert("right_stick_down", keyboard.right_stick_down);
cfgDevice.insert("right_stick_left", keyboard.right_stick_left);
cfgDevice.insert("right_stick_right", keyboard.right_stick_right);
} else if (device.type == config::input::ControllerType::Joystick) {
cfgDevice->insert("left_stick_x", device.joystick.left_stick_x);
cfgDevice->insert("left_stick_x_invert", device.joystick.left_stick_x_invert);
cfgDevice->insert("left_stick_y", device.joystick.left_stick_y);
cfgDevice->insert("left_stick_y_invert", device.joystick.left_stick_y_invert);
cfgDevice->insert("right_stick_x", device.joystick.right_stick_x);
cfgDevice->insert("right_stick_x_invert", device.joystick.right_stick_x_invert);
cfgDevice->insert("right_stick_y", device.joystick.right_stick_y);
cfgDevice->insert("right_stick_y_invert", device.joystick.right_stick_y_invert);
const auto &joystick =
std::get<config::input::InputDeviceJoystick>(device.typeExtra);
cfgDevice.insert("left_stick_x", joystick.left_stick_x);
cfgDevice.insert("left_stick_x_invert", joystick.left_stick_x_invert);
cfgDevice.insert("left_stick_y", joystick.left_stick_y);
cfgDevice.insert("left_stick_y_invert", joystick.left_stick_y_invert);
cfgDevice.insert("right_stick_x", joystick.right_stick_x);
cfgDevice.insert("right_stick_x_invert", joystick.right_stick_x_invert);
cfgDevice.insert("right_stick_y", joystick.right_stick_y);
cfgDevice.insert("right_stick_y_invert", joystick.right_stick_y_invert);
}
devices->push_back(cfgDevice);
}
input->insert("devices", devices);
config->insert("input", input);
// sound
auto sound = config->get_table("sound");
if (!sound) {
sound = cpptoml::make_table();
}
auto sound = config.insert("sound", toml::table()).first->second.as_table();
sound->insert("frame_length", config::sound::frame_length);
config->insert("sound", sound);
// test
auto test = config->get_table("test");
if (!test) {
test = cpptoml::make_table();
}
auto test = config.insert("test", toml::table()).first->second.as_table();
test->insert("timeout_ms", config::test::timeout_ms);
test->insert("timeout_frames", config::test::timeout_frames);
test->insert("dump_drc_frames", config::test::dump_drc_frames);
test->insert("dump_tv_frames", config::test::dump_tv_frames);
test->insert("dump_frames_dir", config::test::dump_frames_dir);
config->insert("test", test);
return true;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <libconfig/config_toml.h>
#include <string>
#include <variant>
#include <vector>
namespace config
@ -16,62 +17,67 @@ enum ControllerType
Joystick,
};
/*
* For keyboard input, each entry is an SDL_SCANCODE_ *constant; for
* joystick input, each entry is the button number, or -2 to let SDL
* choose an appropriate button. In both cases, -1 means nothing is
* assigned.
*/
struct InputDeviceKeyboard
{
int left_stick_up = -1;
int left_stick_down = -1;
int left_stick_left = -1;
int left_stick_right = -1;
int right_stick_up = -1;
int right_stick_down = -1;
int right_stick_left = -1;
int right_stick_right = -1;
};
struct InputDeviceJoystick
{
int left_stick_x = -1;
bool left_stick_x_invert = false;
int left_stick_y = -1;
bool left_stick_y_invert = false;
int right_stick_x = -1;
bool right_stick_x_invert = false;
int right_stick_y = -1;
bool right_stick_y_invert = false;
};
struct InputDevice
{
ControllerType type;
std::string id;
std::string device_name;
// For keyboard input, each entry is an SDL_SCANCODE_* constant; for
// joystick input, each entry is the button number, or -2 to let SDL
// choose an appropriate button. In both cases, -1 means nothing is
// assigned.
int button_up = -1;
int button_down = -1;
int button_left = -1;
int button_right = -1;
int button_a = -1;
int button_b = -1;
int button_x = -1;
int button_y = -1;
int button_trigger_r = -1;
int button_trigger_l = -1;
int button_trigger_zr = -1;
int button_trigger_zl = -1;
int button_stick_l = -1;
int button_stick_r = -1;
int button_plus = -1;
int button_minus = -1;
int button_home = -1;
int button_sync = -1;
int button_up;
int button_down;
int button_left;
int button_right;
int button_a;
int button_b;
int button_x;
int button_y;
int button_trigger_r;
int button_trigger_l;
int button_trigger_zr;
int button_trigger_zl;
int button_stick_l;
int button_stick_r;
int button_plus;
int button_minus;
int button_home;
int button_sync;
union
{
struct
{
int left_stick_up;
int left_stick_down;
int left_stick_left;
int left_stick_right;
int right_stick_up;
int right_stick_down;
int right_stick_left;
int right_stick_right;
} keyboard;
struct
{
int left_stick_x;
bool left_stick_x_invert;
int left_stick_y;
bool left_stick_y_invert;
int right_stick_x;
bool right_stick_x_invert;
int right_stick_y;
bool right_stick_y_invert;
} joystick;
};
std::variant<InputDeviceKeyboard, InputDeviceJoystick> typeExtra;
};
extern std::vector<InputDevice> devices;
@ -112,9 +118,9 @@ void
setupDefaultInputDevices();
bool
loadFrontendToml(std::shared_ptr<cpptoml::table> config);
loadFrontendToml(const toml::table &config);
bool
saveFrontendToml(std::shared_ptr<cpptoml::table> config);
saveFrontendToml(toml::table &config);
} // namespace config

View file

@ -104,35 +104,36 @@ DecafSDL::sampleVpadController(int channel, vpad::Status &status)
status.rightStickX = 0.0f;
status.rightStickY = 0.0f;
if (getState(device->keyboard.left_stick_up)) {
auto &deviceKeyboard = std::get<config::input::InputDeviceKeyboard>(device->typeExtra);
if (getState(deviceKeyboard.left_stick_up)) {
status.leftStickY += 1.0f;
}
if (getState(device->keyboard.left_stick_down)) {
if (getState(deviceKeyboard.left_stick_down)) {
status.leftStickY -= 1.0f;
}
if (getState(device->keyboard.left_stick_left)) {
if (getState(deviceKeyboard.left_stick_left)) {
status.leftStickX -= 1.0f;
}
if (getState(device->keyboard.left_stick_right)) {
if (getState(deviceKeyboard.left_stick_right)) {
status.leftStickX += 1.0f;
}
if (getState(device->keyboard.right_stick_up)) {
if (getState(deviceKeyboard.right_stick_up)) {
status.rightStickY += 1.0f;
}
if (getState(device->keyboard.right_stick_down)) {
if (getState(deviceKeyboard.right_stick_down)) {
status.rightStickY -= 1.0f;
}
if (getState(device->keyboard.right_stick_left)) {
if (getState(deviceKeyboard.right_stick_left)) {
status.rightStickX -= 1.0f;
}
if (getState(device->keyboard.right_stick_right)) {
if (getState(deviceKeyboard.right_stick_right)) {
status.rightStickX += 1.0f;
}
@ -214,25 +215,26 @@ DecafSDL::sampleVpadController(int channel, vpad::Status &status)
status.buttons.b = getState(device->button_b, SDL_CONTROLLER_BUTTON_A);
status.buttons.a = getState(device->button_a, SDL_CONTROLLER_BUTTON_B);
status.leftStickX = getAxis(device->joystick.left_stick_x, SDL_CONTROLLER_AXIS_LEFTX);
status.leftStickY = getAxis(device->joystick.left_stick_y, SDL_CONTROLLER_AXIS_LEFTY);
auto &deviceJoystick = std::get<config::input::InputDeviceJoystick>(device->typeExtra);
status.leftStickX = getAxis(deviceJoystick.left_stick_x, SDL_CONTROLLER_AXIS_LEFTX);
status.leftStickY = getAxis(deviceJoystick.left_stick_y, SDL_CONTROLLER_AXIS_LEFTY);
if (device->joystick.left_stick_x_invert) {
if (deviceJoystick.left_stick_x_invert) {
status.leftStickX = -status.leftStickX;
}
if (device->joystick.left_stick_y_invert) {
if (deviceJoystick.left_stick_y_invert) {
status.leftStickY = -status.leftStickY;
}
status.rightStickX = getAxis(device->joystick.right_stick_x, SDL_CONTROLLER_AXIS_RIGHTX);
status.rightStickY = getAxis(device->joystick.right_stick_y, SDL_CONTROLLER_AXIS_RIGHTY);
status.rightStickX = getAxis(deviceJoystick.right_stick_x, SDL_CONTROLLER_AXIS_RIGHTX);
status.rightStickY = getAxis(deviceJoystick.right_stick_y, SDL_CONTROLLER_AXIS_RIGHTY);
if (device->joystick.right_stick_x_invert) {
if (deviceJoystick.right_stick_x_invert) {
status.rightStickX = -status.rightStickX;
}
if (device->joystick.right_stick_y_invert) {
if (deviceJoystick.right_stick_y_invert) {
status.rightStickY = -status.rightStickY;
}
} else {

View file

@ -156,22 +156,22 @@ start(excmd::parser &parser,
// If config file does not exist, create a default one.
if (!platform::fileExists(configPath)) {
auto toml = cpptoml::make_table();
auto toml = toml::table();
config::saveToTOML(toml, cpuSettings);
config::saveToTOML(toml, gpuSettings);
config::saveToTOML(toml, decafSettings);
config::saveFrontendToml(toml);
std::ofstream out { configPath };
out << (*toml);
out << toml;
}
try {
auto toml = cpptoml::parse_file(configPath);
auto toml = toml::parse_file(configPath);
config::loadFromTOML(toml, cpuSettings);
config::loadFromTOML(toml, gpuSettings);
config::loadFromTOML(toml, decafSettings);
config::loadFrontendToml(toml);
} catch (cpptoml::parse_exception ex) {
} catch (const toml::parse_error &ex) {
configError = ex.what();
}

View file

@ -14,5 +14,5 @@ target_link_libraries(libconfig
libcpu
libdecaf
libgpu
cpptoml
tomlplusplus
excmd)

View file

@ -1,53 +1,72 @@
#pragma once
#include <common/type_traits.h>
#include <cpptoml.h>
#include <libcpu/cpu_config.h>
#include <libdecaf/decaf_config.h>
#include <libgpu/gpu_config.h>
#include <string>
#include <toml++/toml.h>
#include <memory>
#include <type_traits>
namespace config
{
template<typename Type>
inline void
readValue(const std::shared_ptr<cpptoml::table> &config, const char *name, Type &value)
{
value = static_cast<Type>(
config->get_qualified_as<typename safe_underlying_type<Type>::type>(name)
.value_or(static_cast<typename safe_underlying_type<Type>::type>(value)));
}
template<typename Type>
inline void
readArray(const std::shared_ptr<cpptoml::table> &config, const char *name, std::vector<Type> &value)
{
value = config->get_qualified_array_of<Type>(name).value_or(value);
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
cpu::Settings &cpuSettings);
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
decaf::Settings &decafSettings);
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
gpu::Settings &gpuSettings);
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const cpu::Settings &cpuSettings);
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const decaf::Settings &decafSettings);
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const gpu::Settings &gpuSettings);
template<typename Type>
void
readValue(const toml::table &config,
const char *name,
Type &value)
{
auto node = config.at_path(name);
if constexpr (std::is_same_v<Type, bool>) {
if (auto ptr = node.as_boolean()) {
value = ptr->get();
}
} else if constexpr (std::is_integral_v<typename safe_underlying_type<Type>::type>) {
if (auto ptr = node.as_integer()) {
value = static_cast<Type>(ptr->get());
}
} else if constexpr (std::is_floating_point_v<typename safe_underlying_type<Type>::type>) {
if (auto ptr = node.as_floating_point()) {
value = static_cast<Type>(ptr->get());
}
} else if constexpr (std::is_same_v<Type, std::string>) {
if (auto ptr = node.as_string()) {
value = static_cast<Type>(ptr->get());
}
} else {
static_assert(
std::is_same_v<Type, bool> ||
std::is_integral_v<typename safe_underlying_type<Type>::type> ||
std::is_floating_point_v<typename safe_underlying_type<Type>::type> ||
std::is_same_v<Type, std::string>,
"Invalid type passed to readValue");
}
}
} // namespace config

View file

@ -6,6 +6,19 @@
namespace config
{
template<typename Type>
inline void
readArray(const toml::table &config, const char *name, std::vector<Type> &value)
{
auto ptr = config.at_path(name).as_array();
if (ptr) {
value.clear();
for (auto itr = ptr->begin(); itr != ptr->end(); ++itr) {
value.push_back(itr->template as<Type>()->get());
}
}
}
static const char *
translateDisplayBackend(gpu::DisplaySettings::Backend backend)
{
@ -87,7 +100,7 @@ translateViewMode(const std::string &text)
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
cpu::Settings &cpuSettings)
{
readValue(config, "mem.writetrack", cpuSettings.memory.writeTrackEnabled);
@ -103,7 +116,7 @@ loadFromTOML(std::shared_ptr<cpptoml::table> config,
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
decaf::Settings &decafSettings)
{
readValue(config, "debugger.enabled", decafSettings.debugger.enabled);
@ -125,12 +138,12 @@ loadFromTOML(std::shared_ptr<cpptoml::table> config,
readValue(config, "log.to_file", decafSettings.log.to_file);
readValue(config, "log.to_stdout", decafSettings.log.to_stdout);
auto logLevels = config->get_table_qualified("log.levels");
auto logLevels = config.at_path("log.levels").as_table();
if (logLevels) {
decafSettings.log.levels.clear();
for (auto item : *logLevels) {
if (auto level = item.second->as<std::string>()) {
decafSettings.log.levels.emplace_back(item.first, level->get());
if (auto level = item.second.as_string()) {
decafSettings.log.levels.emplace_back(item.first, **level);
}
}
}
@ -153,47 +166,47 @@ loadFromTOML(std::shared_ptr<cpptoml::table> config,
}
bool
loadFromTOML(std::shared_ptr<cpptoml::table> config,
loadFromTOML(const toml::table &config,
gpu::Settings &gpuSettings)
{
readValue(config, "gpu.debug", gpuSettings.debug.debug_enabled);
readValue(config, "gpu.dump_shaders", gpuSettings.debug.dump_shaders);
readValue(config, "gpu.dump_shader_binaries_only", gpuSettings.debug.dump_shader_binaries_only);
auto display = config->get_table("display");
auto display = config.get_as<toml::table>("display");
if (display) {
if (auto text = display->get_as<std::string>("backend"); text) {
if (auto backend = translateDisplayBackend(*text); backend) {
if (auto backend = translateDisplayBackend(**text); backend) {
gpuSettings.display.backend = *backend;
}
}
if (auto text = display->get_as<std::string>("screen_mode"); text) {
if (auto screenMode = translateScreenMode(*text); screenMode) {
if (auto screenMode = translateScreenMode(**text); screenMode) {
gpuSettings.display.screenMode = *screenMode;
}
}
if (auto text = display->get_as<std::string>("view_mode"); text) {
if (auto viewMode = translateViewMode(*text); viewMode) {
if (auto viewMode = translateViewMode(**text); viewMode) {
gpuSettings.display.viewMode = *viewMode;
}
}
if (auto maintainAspectRatio = display->get_as<bool>("maintain_aspect_ratio"); maintainAspectRatio) {
gpuSettings.display.maintainAspectRatio = *maintainAspectRatio;
gpuSettings.display.maintainAspectRatio = **maintainAspectRatio;
}
if (auto splitSeperation = display->get_as<double>("split_seperation"); splitSeperation) {
gpuSettings.display.splitSeperation = *splitSeperation;
gpuSettings.display.splitSeperation = **splitSeperation;
}
if (auto backgroundColour = display->get_array_of<int64_t>("background_colour");
if (auto backgroundColour = display->get_as<toml::array>("background_colour");
backgroundColour && backgroundColour->size() >= 3) {
gpuSettings.display.backgroundColour = {
static_cast<int>(backgroundColour->at(0)),
static_cast<int>(backgroundColour->at(1)),
static_cast<int>(backgroundColour->at(2))
static_cast<int>(**backgroundColour->at(0).as_integer()),
static_cast<int>(**backgroundColour->at(1).as_integer()),
static_cast<int>(**backgroundColour->at(2).as_integer())
};
}
}
@ -202,13 +215,12 @@ loadFromTOML(std::shared_ptr<cpptoml::table> config,
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const cpu::Settings &cpuSettings)
{
// jit
auto jit = config->get_table("jit");
auto jit = config.get_as<toml::table>("jit");
if (!jit) {
jit = cpptoml::make_table();
jit = config.insert("jit", toml::table()).first->second.as_table();
}
jit->insert("enabled", cpuSettings.jit.enabled);
@ -218,49 +230,34 @@ saveToTOML(std::shared_ptr<cpptoml::table> config,
jit->insert("data_cache_size_mb", cpuSettings.jit.dataCacheSizeMB);
jit->insert("rodata_read_only", cpuSettings.jit.rodataReadOnly);
auto opt_flags = cpptoml::make_array();
auto opt_flags = toml::array();
for (auto &flag : cpuSettings.jit.optimisationFlags) {
opt_flags->push_back(flag);
opt_flags.push_back(flag);
}
jit->insert("opt_flags", opt_flags);
config->insert("jit", jit);
return true;
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const decaf::Settings &decafSettings)
{
// debugger
auto debugger = config->get_table("debugger");
if (!debugger) {
debugger = cpptoml::make_table();
}
auto debugger = config.insert("debugger", toml::table()).first->second.as_table();
debugger->insert("enabled", decafSettings.debugger.enabled);
debugger->insert("break_on_entry", decafSettings.debugger.break_on_entry);
debugger->insert("break_on_exit", decafSettings.debugger.break_on_exit);
debugger->insert("gdb_stub", decafSettings.debugger.gdb_stub);
debugger->insert("gdb_stub_port", decafSettings.debugger.gdb_stub_port);
config->insert("debugger", debugger);
// gx2
auto gx2 = config->get_table("gx2");
if (!gx2) {
gx2 = cpptoml::make_table();
}
auto gx2 = config.insert("gx2", toml::table()).first->second.as_table();
gx2->insert("dump_textures", decafSettings.gx2.dump_textures);
gx2->insert("dump_shaders", decafSettings.gx2.dump_shaders);
config->insert("gx2", gx2);
// log
auto log = config->get_table("log");
if (!log) {
log = cpptoml::make_table();
}
auto log = config.insert("log", toml::table()).first->second.as_table();
log->insert("async", decafSettings.log.async);
log->insert("branch_trace", decafSettings.log.branch_trace);
log->insert("directory", decafSettings.log.directory);
@ -270,35 +267,25 @@ saveToTOML(std::shared_ptr<cpptoml::table> config,
log->insert("to_file", decafSettings.log.to_file);
log->insert("to_stdout", decafSettings.log.to_stdout);
auto levels = cpptoml::make_table();
auto levels = toml::table();
for (auto item : decafSettings.log.levels) {
levels->insert(item.first, item.second);
levels.insert(item.first, item.second);
}
log->insert("levels", levels);
log->insert("levels", std::move(levels));
auto hle_trace_filters = cpptoml::make_array();
auto hle_trace_filters = toml::array();
for (auto &filter : decafSettings.log.hle_trace_filters) {
hle_trace_filters->push_back(filter);
hle_trace_filters.push_back(filter);
}
log->insert("hle_trace_filters", hle_trace_filters);
config->insert("log", log);
log->insert("hle_trace_filters", std::move(hle_trace_filters));
// sound
auto sound = config->get_table("sound");
if (!sound) {
sound = cpptoml::make_table();
}
auto sound = config.insert("sound", toml::table()).first->second.as_table();
sound->insert("dump_sounds", decafSettings.sound.dump_sounds);
config->insert("sound", sound);
// system
auto system = config->get_table("system");
if (!system) {
system = cpptoml::make_table();
}
auto system = config.insert("system", toml::table()).first->second.as_table();
system->insert("region", static_cast<int>(decafSettings.system.region));
system->insert("hfio_path", decafSettings.system.hfio_path);
system->insert("mlc_path", decafSettings.system.mlc_path);
@ -309,59 +296,43 @@ saveToTOML(std::shared_ptr<cpptoml::table> config,
system->insert("content_path", decafSettings.system.content_path);
system->insert("time_scale", decafSettings.system.time_scale);
auto lle_modules = cpptoml::make_array();
auto lle_modules = toml::array();
for (auto &name : decafSettings.system.lle_modules) {
lle_modules->push_back(name);
lle_modules.push_back(name);
}
system->insert("lle_modules", std::move(lle_modules));
system->insert("lle_modules", lle_modules);
auto title_directories = cpptoml::make_array();
auto title_directories = toml::array();
for (auto &name : decafSettings.system.title_directories) {
title_directories->push_back(name);
title_directories.push_back(name);
}
system->insert("title_directories", title_directories);
config->insert("system", system);
system->insert("title_directories", std::move(title_directories));
return true;
}
bool
saveToTOML(std::shared_ptr<cpptoml::table> config,
saveToTOML(toml::table &config,
const gpu::Settings &gpuSettings)
{
// gpu
auto gpu = config->get_table("gpu");
if (!gpu) {
gpu = cpptoml::make_table();
}
auto gpu = config.insert("gpu", toml::table()).first->second.as_table();
gpu->insert("debug", gpuSettings.debug.debug_enabled);
gpu->insert("dump_shaders", gpuSettings.debug.dump_shaders);
gpu->insert("dump_shader_binaries_only", gpuSettings.debug.dump_shader_binaries_only);
config->insert("gpu", gpu);
// display
auto display = config->get_table("display");
if (!display) {
display = cpptoml::make_table();
}
auto display = config.insert("display", toml::table()).first->second.as_table();
display->insert("backend", translateDisplayBackend(gpuSettings.display.backend));
display->insert("screen_mode", translateScreenMode(gpuSettings.display.screenMode));
display->insert("view_mode", translateViewMode(gpuSettings.display.viewMode));
display->insert("maintain_aspect_ratio", gpuSettings.display.maintainAspectRatio);
display->insert("split_seperation", gpuSettings.display.splitSeperation);
auto backgroundColour = cpptoml::make_array();
backgroundColour->push_back(gpuSettings.display.backgroundColour[0]);
backgroundColour->push_back(gpuSettings.display.backgroundColour[1]);
backgroundColour->push_back(gpuSettings.display.backgroundColour[2]);
display->insert("background_colour", backgroundColour);
config->insert("display", display);
auto backgroundColour = toml::array();
backgroundColour.push_back(gpuSettings.display.backgroundColour[0]);
backgroundColour.push_back(gpuSettings.display.backgroundColour[1]);
backgroundColour.push_back(gpuSettings.display.backgroundColour[2]);
display->insert("background_colour", std::move(backgroundColour));
return true;
}