154 lines
4.7 KiB
C++
154 lines
4.7 KiB
C++
|
|
#include <fstream>
|
|
|
|
#ifdef _WIN32
|
|
#include <shlobj.h>
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include "Config.h"
|
|
#include "ConfigConvert.hpp"
|
|
#include "Environment.h"
|
|
#include "core/FileSystem.hpp"
|
|
#include "interop/interop.hpp"
|
|
#include "utility/yaml.hpp"
|
|
|
|
using namespace openloco::interop;
|
|
|
|
namespace openloco::config
|
|
{
|
|
static loco_global<config_t, 0x0050AEB4> _config;
|
|
static new_config _new_config;
|
|
static YAML::Node _config_yaml;
|
|
|
|
config_t& get()
|
|
{
|
|
return _config;
|
|
}
|
|
|
|
new_config& getNew()
|
|
{
|
|
return _new_config;
|
|
}
|
|
|
|
// 0x00441A6C
|
|
config_t& read()
|
|
{
|
|
call(0x00441A6C);
|
|
return _config;
|
|
}
|
|
|
|
// 0x00441BB8
|
|
void write()
|
|
{
|
|
call(0x00441BB8);
|
|
writeNewConfig();
|
|
}
|
|
|
|
new_config& readNewConfig()
|
|
{
|
|
auto configPath = environment::getPath(environment::path_id::openloco_yml);
|
|
|
|
if (!fs::exists(configPath))
|
|
return _new_config;
|
|
|
|
// WARNING: on Windows, YAML::LoadFile only supports ANSI paths
|
|
_config_yaml = YAML::LoadFile(configPath.string());
|
|
|
|
const auto& config = _config_yaml;
|
|
auto& displayNode = config["display"];
|
|
if (displayNode && displayNode.IsMap())
|
|
{
|
|
auto& displayConfig = _new_config.display;
|
|
displayConfig.mode = displayNode["mode"].as<screen_mode>(screen_mode::window);
|
|
displayConfig.index = displayNode["index"].as<int32_t>(0);
|
|
displayConfig.window_resolution = displayNode["window_resolution"].as<resolution_t>();
|
|
displayConfig.fullscreen_resolution = displayNode["fullscreen_resolution"].as<resolution_t>();
|
|
}
|
|
|
|
auto& audioNode = config["audio"];
|
|
if (audioNode && audioNode.IsMap())
|
|
{
|
|
auto& audioConfig = _new_config.audio;
|
|
audioConfig.device = audioNode["device"].as<std::string>("");
|
|
if (audioNode["play_title_music"])
|
|
audioConfig.play_title_music = audioNode["play_title_music"].as<bool>();
|
|
}
|
|
|
|
if (config["loco_install_path"])
|
|
_new_config.loco_install_path = config["loco_install_path"].as<std::string>();
|
|
if (config["language"])
|
|
_new_config.language = config["language"].as<std::string>();
|
|
if (config["breakdowns_disabled"])
|
|
_new_config.breakdowns_disabled = config["breakdowns_disabled"].as<bool>();
|
|
if (config["companyAIDisabled"])
|
|
_new_config.companyAIDisabled = config["companyAIDisabled"].as<bool>();
|
|
if (config["scale_factor"])
|
|
_new_config.scale_factor = config["scale_factor"].as<float>();
|
|
if (config["zoom_to_cursor"])
|
|
_new_config.zoom_to_cursor = config["zoom_to_cursor"].as<bool>();
|
|
|
|
return _new_config;
|
|
}
|
|
|
|
void writeNewConfig()
|
|
{
|
|
auto configPath = environment::getPath(environment::path_id::openloco_yml);
|
|
auto dir = configPath.parent_path();
|
|
if (!fs::is_directory(dir))
|
|
{
|
|
fs::create_directories(dir);
|
|
// clang-format off
|
|
fs::permissions(
|
|
dir,
|
|
fs::perms::owner_all |
|
|
fs::perms::group_read | fs::perms::group_exec |
|
|
fs::perms::others_read | fs::perms::others_exec
|
|
);
|
|
// clang-format on
|
|
}
|
|
|
|
auto& node = _config_yaml;
|
|
|
|
// Display
|
|
const auto& displayConfig = _new_config.display;
|
|
auto displayNode = node["display"];
|
|
displayNode["mode"] = displayConfig.mode;
|
|
if (displayConfig.index != 0)
|
|
{
|
|
displayNode["index"] = displayConfig.index;
|
|
}
|
|
else
|
|
{
|
|
displayNode.remove("index");
|
|
}
|
|
displayNode["window_resolution"] = displayConfig.window_resolution;
|
|
displayNode["fullscreen_resolution"] = displayConfig.fullscreen_resolution;
|
|
node["display"] = displayNode;
|
|
|
|
// Audio
|
|
const auto& audioConfig = _new_config.audio;
|
|
auto audioNode = node["audio"];
|
|
audioNode["device"] = audioConfig.device;
|
|
if (audioConfig.device.empty())
|
|
{
|
|
audioNode.remove("device");
|
|
}
|
|
audioNode["play_title_music"] = audioConfig.play_title_music;
|
|
node["audio"] = audioNode;
|
|
|
|
node["loco_install_path"] = _new_config.loco_install_path;
|
|
node["language"] = _new_config.language;
|
|
node["breakdowns_disabled"] = _new_config.breakdowns_disabled;
|
|
node["companyAIDisabled"] = _new_config.companyAIDisabled;
|
|
node["scale_factor"] = _new_config.scale_factor;
|
|
node["zoom_to_cursor"] = _new_config.zoom_to_cursor;
|
|
|
|
std::ofstream stream(configPath);
|
|
if (stream.is_open())
|
|
{
|
|
stream << node << std::endl;
|
|
}
|
|
}
|
|
}
|