Files
melonDS/src/frontend/qt_sdl/Config.cpp
2024-05-24 20:32:28 +02:00

823 lines
23 KiB
C++

/*
Copyright 2016-2023 melonDS team
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <iostream>
#include <fstream>
#include <regex>
#include "toml/toml.hpp"
#include "Platform.h"
#include "Config.h"
#include "FrontendUtil.h"
#include "main.h"
using namespace std::string_literals;
namespace Config
{
using namespace melonDS;
int WindowWidth;
int WindowHeight;
bool WindowMaximized;
int ScreenRotation;
int ScreenGap;
int ScreenLayout;
bool ScreenSwap;
int ScreenSizing;
bool IntegerScaling;
int ScreenAspectTop;
int ScreenAspectBot;
bool ScreenFilter;
bool ScreenUseGL;
bool ScreenVSync;
int ScreenVSyncInterval;
int _3DRenderer;
bool Threaded3D;
int GL_ScaleFactor;
bool GL_BetterPolygons;
bool GL_HiresCoordinates;
bool FirmwareOverrideSettings;
std::string FirmwareUsername;
int FirmwareLanguage;
int FirmwareBirthdayMonth;
int FirmwareBirthdayDay;
int FirmwareFavouriteColour;
std::string FirmwareMessage;
std::string FirmwareMAC;
std::string WifiSettingsPath = "wfcsettings.bin"; // Should this be configurable?
int MPAudioMode;
int MPRecvTimeout;
std::string LANDevice;
bool DirectLAN;
std::string SaveFilePath;
std::string SavestatePath;
std::string CheatFilePath;
bool MouseHide;
int MouseHideSeconds;
bool PauseLostFocus;
std::string UITheme;
int64_t RTCOffset;
bool DSBatteryLevelOkay;
int DSiBatteryLevel;
bool DSiBatteryCharging;
CameraConfig Camera[2];
const char* kConfigFile = "melonDS.toml";
const char* kLegacyConfigFile = "melonDS.ini";
const char* kLegacyUniqueConfigFile = "melonDS.%d.ini";
toml::value RootTable;
DefaultList<int> DefaultInts =
{
{"Instance*.Keyboard", -1},
{"Instance*.Joystick", -1},
{"Instance*.Window*.Width", 256},
{"Instance*.Window*.Height", 384},
{"Screen.VSyncInterval", 1},
{"3D.GL.ScaleFactor", 1},
{"MaxFPS", 1000},
#ifdef JIT_ENABLED
{"JIT.MaxBlockSize", 32},
#endif
{"Instance*.Firmware.Language", 1},
{"Instance*.Firmware.BirthdayMonth", 1},
{"Instance*.Firmware.BirthdayDay", 1},
{"MP.AudioMode", 1},
{"MP.RecvTimeout", 25},
{"Audio.Volume", 256},
{"Mic.InputType", 1},
{"Mouse.HideSeconds", 5},
{"Instance*.DSi.Battery.Level", 0xF},
#ifdef GDBSTUB_ENABLED
{"Instance*.Gdb.ARM7.Port", 3334},
{"Instance*.Gdb.ARM9.Port", 3333},
#endif
};
RangeList IntRanges =
{
{"Emu.ConsoleType", {0, 1}},
#ifdef OGLRENDERER_ENABLED
{"3D.Renderer", {0, 1}},
#else
{"3D.Renderer", {0, 0}},
#endif
{"Screen.VSyncInterval", {1, 20}},
{"3D.GL.ScaleFactor", {1, 16}},
{"Audio.Interpolation", {0, 3}},
{"Instance*.Audio.Volume", {0, 256}},
{"Mic.InputType", {0, micInputType_MAX-1}},
{"Instance*.Window*.ScreenRotation", {0, Frontend::screenRot_MAX-1}},
{"Instance*.Window*.ScreenGap", {0, 500}},
{"Instance*.Window*.ScreenLayout", {0, Frontend::screenLayout_MAX-1}},
{"Instance*.Window*.ScreenSizing", {0, Frontend::screenSizing_MAX-1}},
{"Instance*.Window*.ScreenAspectTop", {0, AspectRatiosNum-1}},
{"Instance*.Window*.ScreenAspectBot", {0, AspectRatiosNum-1}},
};
DefaultList<bool> DefaultBools =
{
{"Screen.Filter", true},
{"3D.Soft.Threaded3D", true},
{"LimitFPS", true},
{"Window*.ShowOSD", true},
{"Emu.DirectBoot", true},
#ifdef JIT_ENABLED
{"JIT.BranchOptimisations", true},
{"JIT.LiteralOptimisations", true},
#ifndef __APPLE__
{"JIT.FastMemory", true},
#endif
#endif
};
DefaultList<std::string> DefaultStrings =
{
{"DLDI.ImagePath", "dldi.bin"},
{"DSi.SD.ImagePath", "dsisd.bin"},
{"Instance*.Firmware.Username", "melonDS"}
};
LegacyEntry LegacyFile[] =
{
{"Key_A", 0, "Keyboard.A", true},
{"Key_B", 0, "Keyboard.B", true},
{"Key_Select", 0, "Keyboard.Select", true},
{"Key_Start", 0, "Keyboard.Start", true},
{"Key_Right", 0, "Keyboard.Right", true},
{"Key_Left", 0, "Keyboard.Left", true},
{"Key_Up", 0, "Keyboard.Up", true},
{"Key_Down", 0, "Keyboard.Down", true},
{"Key_R", 0, "Keyboard.R", true},
{"Key_L", 0, "Keyboard.L", true},
{"Key_X", 0, "Keyboard.X", true},
{"Key_Y", 0, "Keyboard.Y", true},
{"Joy_A", 0, "Joystick.A", true},
{"Joy_B", 0, "Joystick.B", true},
{"Joy_Select", 0, "Joystick.Select", true},
{"Joy_Start", 0, "Joystick.Start", true},
{"Joy_Right", 0, "Joystick.Right", true},
{"Joy_Left", 0, "Joystick.Left", true},
{"Joy_Up", 0, "Joystick.Up", true},
{"Joy_Down", 0, "Joystick.Down", true},
{"Joy_R", 0, "Joystick.R", true},
{"Joy_L", 0, "Joystick.L", true},
{"Joy_X", 0, "Joystick.X", true},
{"Joy_Y", 0, "Joystick.Y", true},
{"HKKey_Lid", 0, "Keyboard.HK_Lid", true},
{"HKKey_Mic", 0, "Keyboard.HK_Mic", true},
{"HKKey_Pause", 0, "Keyboard.HK_Pause", true},
{"HKKey_Reset", 0, "Keyboard.HK_Reset", true},
{"HKKey_FastForward", 0, "Keyboard.HK_FastForward", true},
{"HKKey_FastForwardToggle", 0, "Keyboard.HK_FastForwardToggle", true},
{"HKKey_FullscreenToggle", 0, "Keyboard.HK_FullscreenToggle", true},
{"HKKey_SwapScreens", 0, "Keyboard.HK_SwapScreens", true},
{"HKKey_SwapScreenEmphasis", 0, "Keyboard.HK_SwapScreenEmphasis", true},
{"HKKey_SolarSensorDecrease", 0, "Keyboard.HK_SolarSensorDecrease", true},
{"HKKey_SolarSensorIncrease", 0, "Keyboard.HK_SolarSensorIncrease", true},
{"HKKey_FrameStep", 0, "Keyboard.HK_FrameStep", true},
{"HKKey_PowerButton", 0, "Keyboard.HK_PowerButton", true},
{"HKKey_VolumeUp", 0, "Keyboard.HK_VolumeUp", true},
{"HKKey_VolumeDown", 0, "Keyboard.HK_VolumeDown", true},
{"HKJoy_Lid", 0, "Joystick.HK_Lid", true},
{"HKJoy_Mic", 0, "Joystick.HK_Mic", true},
{"HKJoy_Pause", 0, "Joystick.HK_Pause", true},
{"HKJoy_Reset", 0, "Joystick.HK_Reset", true},
{"HKJoy_FastForward", 0, "Joystick.HK_FastForward", true},
{"HKJoy_FastForwardToggle", 0, "Joystick.HK_FastForwardToggle", true},
{"HKJoy_FullscreenToggle", 0, "Joystick.HK_FullscreenToggle", true},
{"HKJoy_SwapScreens", 0, "Joystick.HK_SwapScreens", true},
{"HKJoy_SwapScreenEmphasis", 0, "Joystick.HK_SwapScreenEmphasis", true},
{"HKJoy_SolarSensorDecrease", 0, "Joystick.HK_SolarSensorDecrease", true},
{"HKJoy_SolarSensorIncrease", 0, "Joystick.HK_SolarSensorIncrease", true},
{"HKJoy_FrameStep", 0, "Joystick.HK_FrameStep", true},
{"HKJoy_PowerButton", 0, "Joystick.HK_PowerButton", true},
{"HKJoy_VolumeUp", 0, "Joystick.HK_VolumeUp", true},
{"HKJoy_VolumeDown", 0, "Joystick.HK_VolumeDown", true},
{"JoystickID", 0, "JoystickID", true},
{"WindowWidth", 0, "Window0.Width", true},
{"WindowHeight", 0, "Window0.Height", true},
{"WindowMax", 1, "Window0.Maximized", true},
{"ScreenRotation", 0, "Window0.ScreenRotation", true},
{"ScreenGap", 0, "Window0.ScreenGap", true},
{"ScreenLayout", 0, "Window0.ScreenLayout", true},
{"ScreenSwap", 1, "Window0.ScreenSwap", true},
{"ScreenSizing", 0, "Window0.ScreenSizing", true},
{"IntegerScaling", 1, "Window0.IntegerScaling", true},
{"ScreenAspectTop",0, "Window0.ScreenAspectTop", true},
{"ScreenAspectBot",0, "Window0.ScreenAspectBot", true},
{"ScreenFilter", 1, "Screen.Filter", false},
{"ScreenUseGL", 1, "Screen.UseGL", false},
{"ScreenVSync", 1, "Screen.VSync", false},
{"ScreenVSyncInterval", 0, "Screen.VSyncInterval", false},
{"3DRenderer", 0, "3D.Renderer", false},
{"Threaded3D", 1, "3D.Soft.Threaded3D", false},
{"GL_ScaleFactor", 0, "3D.GL.ScaleFactor", false},
{"GL_BetterPolygons", 1, "3D.GL.BetterPolygons", false},
{"LimitFPS", 1, "LimitFPS", false},
{"MaxFPS", 0, "MaxFPS", false},
{"AudioSync", 1, "AudioSync", false},
{"ShowOSD", 1, "Window0.ShowOSD", true},
{"ConsoleType", 0, "Emu.ConsoleType", false},
{"DirectBoot", 1, "Emu.DirectBoot", false},
#ifdef JIT_ENABLED
{"JIT_Enable", 1, "JIT.Enable", false},
{"JIT_MaxBlockSize", 0, "JIT.MaxBlockSize", false},
{"JIT_BranchOptimisations", 1, "JIT.BranchOptimisations", false},
{"JIT_LiteralOptimisations", 1, "JIT.LiteralOptimisations", false},
{"JIT_FastMemory", 1, "JIT.FastMemory", false},
#endif
{"ExternalBIOSEnable", 1, "Emu.ExternalBIOSEnable", false},
{"BIOS9Path", 2, "DS.BIOS9Path", false},
{"BIOS7Path", 2, "DS.BIOS7Path", false},
{"FirmwarePath", 2, "DS.FirmwarePath", false},
{"DSiBIOS9Path", 2, "DSi.BIOS9Path", false},
{"DSiBIOS7Path", 2, "DSi.BIOS7Path", false},
{"DSiFirmwarePath", 2, "DSi.FirmwarePath", false},
{"DSiNANDPath", 2, "DSi.NANDPath", false},
{"DLDIEnable", 1, "DLDI.Enable", false},
{"DLDISDPath", 2, "DLDI.ImagePath", false},
{"DLDISize", 0, "DLDI.ImageSize", false},
{"DLDIReadOnly", 1, "DLDI.ReadOnly", false},
{"DLDIFolderSync", 1, "DLDI.FolderSync", false},
{"DLDIFolderPath", 2, "DLDI.FolderPath", false},
{"DSiSDEnable", 1, "DSi.SD.Enable", false},
{"DSiSDPath", 2, "DSi.SD.ImagePath", false},
{"DSiSDSize", 0, "DSi.SD.ImageSize", false},
{"DSiSDReadOnly", 1, "DSi.SD.ReadOnly", false},
{"DSiSDFolderSync", 1, "DSi.SD.FolderSync", false},
{"DSiSDFolderPath", 2, "DSi.SD.FolderPath", false},
{"FirmwareOverrideSettings", 1, "Firmware.OverrideSettings", true},
{"FirmwareUsername", 2, "Firmware.Username", true},
{"FirmwareLanguage", 0, "Firmware.Language", true},
{"FirmwareBirthdayMonth", 0, "Firmware.BirthdayMonth", true},
{"FirmwareBirthdayDay", 0, "Firmware.BirthdayDay", true},
{"FirmwareFavouriteColour", 0, "Firmware.FavouriteColour", true},
{"FirmwareMessage", 2, "Firmware.Message", true},
{"FirmwareMAC", 2, "Firmware.MAC", true},
{"MPAudioMode", 0, "MP.AudioMode", false},
{"MPRecvTimeout", 0, "MP.RecvTimeout", false},
{"LANDevice", 2, "LAN.Device", false},
{"DirectLAN", 1, "LAN.DirectMode", false},
{"SavStaRelocSRAM", 1, "Savestate.RelocSRAM", false},
{"AudioInterp", 0, "Audio.Interpolation", false},
{"AudioBitDepth", 0, "Audio.BitDepth", false},
{"AudioVolume", 0, "Audio.Volume", true},
{"DSiVolumeSync", 1, "Audio.DSiVolumeSync", true},
{"MicInputType", 0, "Mic.InputType", false},
{"MicDevice", 2, "Mic.Device", false},
{"MicWavPath", 2, "Mic.WavPath", false},
{"LastROMFolder", 2, "LastROMFolder", false},
{"LastBIOSFolder", 2, "LastBIOSFolder", false},
{"RecentROM_0", 4, "RecentROM[0]", false},
{"RecentROM_1", 4, "RecentROM[1]", false},
{"RecentROM_2", 4, "RecentROM[2]", false},
{"RecentROM_3", 4, "RecentROM[3]", false},
{"RecentROM_4", 4, "RecentROM[4]", false},
{"RecentROM_5", 4, "RecentROM[5]", false},
{"RecentROM_6", 4, "RecentROM[6]", false},
{"RecentROM_7", 4, "RecentROM[7]", false},
{"RecentROM_8", 4, "RecentROM[8]", false},
{"RecentROM_9", 4, "RecentROM[9]", false},
{"SaveFilePath", 2, "SaveFilePath", true},
{"SavestatePath", 2, "SavestatePath", true},
{"CheatFilePath", 2, "CheatFilePath", true},
{"EnableCheats", 1, "EnableCheats", true},
{"MouseHide", 1, "Mouse.Hide", false},
{"MouseHideSeconds", 0, "Mouse.HideSeconds", false},
{"PauseLostFocus", 1, "PauseLostFocus", false},
{"UITheme", 2, "UITheme", false},
{"RTCOffset", 3, "RTC.Offset", true},
{"DSBatteryLevelOkay", 1, "DS.Battery.LevelOkay", true},
{"DSiBatteryLevel", 0, "DSi.Battery.Level", true},
{"DSiBatteryCharging", 1, "DSi.Battery.Charging", true},
{"DSiFullBIOSBoot", 1, "DSi.FullBIOSBoot", true},
#ifdef GDBSTUB_ENABLED
{"GdbEnabled", 1, "Gdb.Enabled", false},
{"GdbPortARM7", 0, "Gdb.ARM7.Port", true},
{"GdbPortARM9", 0, "Gdb.ARM9.Port", true},
{"GdbARM7BreakOnStartup", 1, "Gdb.ARM7.BreakOnStartup", true},
{"GdbARM9BreakOnStartup", 1, "Gdb.ARM9.BreakOnStartup", true},
#endif
{"Camera0_InputType", 0, "DSi.Camera0.InputType", false},
{"Camera0_ImagePath", 2, "DSi.Camera0.ImagePath", false},
{"Camera0_CamDeviceName", 2, "DSi.Camera0.DeviceName", false},
{"Camera0_XFlip", 1, "DSi.Camera0.XFlip", false},
{"Camera1_InputType", 0, "DSi.Camera1.InputType", false},
{"Camera1_ImagePath", 2, "DSi.Camera1.ImagePath", false},
{"Camera1_CamDeviceName", 2, "DSi.Camera1.DeviceName", false},
{"Camera1_XFlip", 1, "DSi.Camera1.XFlip", false},
{"", -1, "", false}
};
Array::Array(toml::value& data) : Data(data)
{
}
size_t Array::Size()
{
return Data.size();
}
void Array::Clear()
{
toml::array newarray;
Data = newarray;
}
Array Array::GetArray(const int id)
{
while (Data.size() < id+1)
Data.push_back(toml::array());
toml::value& arr = Data[id];
if (!arr.is_array())
arr = toml::array();
return Array(arr);
}
int Array::GetInt(const int id)
{
while (Data.size() < id+1)
Data.push_back(0);
toml::value& tval = Data[id];
if (!tval.is_integer())
tval = 0;
return (int)tval.as_integer();
}
int64_t Array::GetInt64(const int id)
{
while (Data.size() < id+1)
Data.push_back(0);
toml::value& tval = Data[id];
if (!tval.is_integer())
tval = 0;
return tval.as_integer();
}
bool Array::GetBool(const int id)
{
while (Data.size() < id+1)
Data.push_back(false);
toml::value& tval = Data[id];
if (!tval.is_boolean())
tval = false;
return tval.as_boolean();
}
std::string Array::GetString(const int id)
{
while (Data.size() < id+1)
Data.push_back("");
toml::value& tval = Data[id];
if (!tval.is_string())
tval = "";
return tval.as_string();
}
void Array::SetInt(const int id, int val)
{
while (Data.size() < id+1)
Data.push_back(0);
toml::value& tval = Data[id];
tval = val;
}
void Array::SetInt64(const int id, int64_t val)
{
while (Data.size() < id+1)
Data.push_back(0);
toml::value& tval = Data[id];
tval = val;
}
void Array::SetBool(const int id, bool val)
{
while (Data.size() < id+1)
Data.push_back(false);
toml::value& tval = Data[id];
tval = val;
}
void Array::SetString(const int id, const std::string& val)
{
while (Data.size() < id+1)
Data.push_back("");
toml::value& tval = Data[id];
tval = val;
}
/*Table::Table()// : Data(toml::value())
{
Data = toml::value();
PathPrefix = "";
}*/
Table::Table(toml::value& data, const std::string& path) : Data(data)
{
if (path.empty())
PathPrefix = "";
else
PathPrefix = path + ".";
}
Table& Table::operator=(const Table& b)
{
Data = b.Data;
PathPrefix = b.PathPrefix;
return *this;
}
Array Table::GetArray(const std::string& path)
{
toml::value& arr = ResolvePath(path);
if (!arr.is_array())
arr = toml::array();
return Array(arr);
}
Table Table::GetTable(const std::string& path, const std::string& defpath)
{
toml::value& tbl = ResolvePath(path);
if (!tbl.is_table())
{
toml::value defval = toml::table();
if (!defpath.empty())
defval = ResolvePath(defpath);
tbl = defval;
}
return Table(tbl, PathPrefix + path);
}
int Table::GetInt(const std::string& path)
{
toml::value& tval = ResolvePath(path);
if (!tval.is_integer())
tval = FindDefault(path, 0, DefaultInts);
int ret = (int)tval.as_integer();
std::regex rng_re("\\d+");
std::string rngkey = std::regex_replace(PathPrefix+path, rng_re, "*");
if (IntRanges.count(rngkey) != 0)
{
auto& range = IntRanges[rngkey];
ret = std::clamp(ret, std::get<0>(range), std::get<1>(range));
}
return ret;
}
int64_t Table::GetInt64(const std::string& path)
{
toml::value& tval = ResolvePath(path);
if (!tval.is_integer())
tval = 0;
return tval.as_integer();
}
bool Table::GetBool(const std::string& path)
{
toml::value& tval = ResolvePath(path);
if (!tval.is_boolean())
tval = FindDefault(path, false, DefaultBools);
return tval.as_boolean();
}
std::string Table::GetString(const std::string& path)
{
toml::value& tval = ResolvePath(path);
if (!tval.is_string())
tval = FindDefault(path, ""s, DefaultStrings);
return tval.as_string();
}
void Table::SetInt(const std::string& path, int val)
{
std::regex rng_re("\\d+");
std::string rngkey = std::regex_replace(PathPrefix+path, rng_re, "*");
if (IntRanges.count(rngkey) != 0)
{
auto& range = IntRanges[rngkey];
val = std::clamp(val, std::get<0>(range), std::get<1>(range));
}
toml::value& tval = ResolvePath(path);
tval = val;
}
void Table::SetInt64(const std::string& path, int64_t val)
{
toml::value& tval = ResolvePath(path);
tval = val;
}
void Table::SetBool(const std::string& path, bool val)
{
toml::value& tval = ResolvePath(path);
tval = val;
}
void Table::SetString(const std::string& path, const std::string& val)
{
toml::value& tval = ResolvePath(path);
tval = val;
}
toml::value& Table::ResolvePath(const std::string& path)
{
toml::value* ret = &Data;
std::string tmp = path;
size_t sep;
while ((sep = tmp.find('.')) != std::string::npos)
{
ret = &(*ret)[tmp.substr(0, sep)];
tmp = tmp.substr(sep+1);
}
return (*ret)[tmp];
}
template<typename T> T Table::FindDefault(const std::string& path, T def, DefaultList<T> list)
{
std::regex def_re("\\d+");
std::string defkey = std::regex_replace(PathPrefix+path, def_re, "*");
T ret = def;
while (list.count(defkey) == 0)
{
if (defkey.empty()) break;
size_t sep = defkey.rfind('.');
if (sep == std::string::npos) break;
defkey = defkey.substr(0, sep);
}
if (list.count(defkey) != 0)
ret = list[defkey];
return ret;
}
bool LoadLegacyFile(int inst)
{
Platform::FileHandle* f;
if (inst > 0)
{
char name[100] = {0};
snprintf(name, 99, kLegacyUniqueConfigFile, inst+1);
f = Platform::OpenLocalFile(name, Platform::FileMode::ReadText);
}
else
{
f = Platform::OpenLocalFile(kLegacyConfigFile, Platform::FileMode::ReadText);
}
if (!f) return true;
printf("PARSING LEGACY INI %d\n", inst);
toml::value* root;// = GetLocalTable(inst);
if (inst == -1)
root = &RootTable;
else
root = &RootTable["Instance" + std::to_string(inst)];
char linebuf[1024];
char entryname[32];
char entryval[1024];
while (!Platform::IsEndOfFile(f))
{
if (!Platform::FileReadLine(linebuf, 1024, f))
break;
int ret = sscanf(linebuf, "%31[A-Za-z_0-9]=%[^\t\r\n]", entryname, entryval);
entryname[31] = '\0';
if (ret < 2) continue;
for (LegacyEntry* entry = &LegacyFile[0]; entry->Type != -1; entry++)
{
if (!strncmp(entry->Name, entryname, 32))
{
if (!(entry->InstanceUnique ^ (inst == -1)))
break;
printf("entry: %s -> %s, %d\n", entry->Name, entry->TOMLPath, entry->InstanceUnique);
std::string path = entry->TOMLPath;
toml::value* table = root;
size_t sep;
while ((sep = path.find('.')) != std::string::npos)
{printf("%s->", path.substr(0,sep).c_str());
table = &(*table)[path.substr(0, sep)];
path = path.substr(sep+1);
}
printf("%s\n", path.c_str());
int arrayid = -1;
if (path[path.size()-1] == ']')
{
size_t tmp = path.rfind('[');
arrayid = std::stoi(path.substr(tmp+1, path.size()-tmp-2));
path = path.substr(0, tmp);
}
printf("path %s id %d\n", path.c_str(), arrayid);
toml::value& val = (*table)[path];
switch (entry->Type)
{
case 0:
val = strtol(entryval, nullptr, 10);
break;
case 1:
val = !!strtol(entryval, nullptr, 10);
break;
case 2:
val = entryval;
break;
case 3:
val = strtoll(entryval, nullptr, 10);
break;
case 4:
if (!val.is_array()) val = toml::array();
while (val.size() < arrayid+1)
val.push_back("");
val[arrayid] = entryval;
//val.push_back(entryval);
break;
}
break;
}
}
}
CloseFile(f);
return true;
}
bool LoadLegacy()
{
for (int i = -1; i < 16; i++)
LoadLegacyFile(i);
return true;
}
bool Load()
{
auto cfgpath = Platform::GetLocalFilePath(kConfigFile);
if (!Platform::CheckFileWritable(cfgpath))
return false;
RootTable = toml::value();
if (!Platform::FileExists(cfgpath))
return LoadLegacy();
try
{
RootTable = toml::parse(cfgpath);
}
catch (toml::syntax_error& err)
{
//RootTable = toml::table();
}
//
return true;
}
void Save()
{
auto cfgpath = Platform::GetLocalFilePath(kConfigFile);
printf("save\n");
if (!Platform::CheckFileWritable(cfgpath))
return;
printf("zirz\n");
/*RootTable["test"] = 4444;
RootTable["teste.derp"] = 5555;
RootTable["testa"]["fazil"] = 6666;*/
//std::string derp = "sfsdf";
//toml::serializer<std::string> vorp(RootTable);
//toml::serializer<toml::string> zarp;
//std::cout << RootTable;
printf("blarg\n");
std::ofstream file;
file.open(cfgpath, std::ofstream::out | std::ofstream::trunc);
file << RootTable;
file.close();
}
Table GetLocalTable(int instance)
{
if (instance == -1)
return Table(RootTable, "");
std::string key = "Instance" + std::to_string(instance);
toml::value& tbl = RootTable[key];
if (tbl.is_uninitialized())
RootTable[key] = RootTable["Instance0"];
return Table(tbl, key);
}
}