mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-07 23:45:40 +02:00
Allow overriding mkxp.json from uder data directory
This commit is contained in:
parent
d568423774
commit
36cdbb95b6
2 changed files with 77 additions and 68 deletions
100
src/config.cpp
100
src/config.cpp
|
@ -72,12 +72,13 @@ bool copyObject(json::value &dest, json::value &src, const char *objectName = ""
|
||||||
if ((it.second.is_array() && destVec[it.first].is_array()) ||
|
if ((it.second.is_array() && destVec[it.first].is_array()) ||
|
||||||
(it.second.is_number() && destVec[it.first].is_number()) ||
|
(it.second.is_number() && destVec[it.first].is_number()) ||
|
||||||
(it.second.is_string() && destVec[it.first].is_string()) ||
|
(it.second.is_string() && destVec[it.first].is_string()) ||
|
||||||
(it.second.is_boolean() && destVec[it.first].is_boolean()) )
|
(it.second.is_boolean() && destVec[it.first].is_boolean()) ||
|
||||||
|
(destVec[it.first].is_null()))
|
||||||
{
|
{
|
||||||
destVec[it.first] = it.second;
|
destVec[it.first] = it.second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Debug() << "Invalid or unrecognized variable in configuration:" << objectName << it.first;
|
Debug() << "Invalid variable in configuration:" << objectName << it.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -96,6 +97,30 @@ bool getEnvironmentBool(const char *env, bool defaultValue) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json::value readConfFile(const char *path) {
|
||||||
|
|
||||||
|
json::value ret(0);
|
||||||
|
if (!mkxp_fs::fileExists(path)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::string cfg = mkxp_fs::contentsOfFileAsString(path);
|
||||||
|
ret = json::parse5(Encoding::convertString(cfg));
|
||||||
|
}
|
||||||
|
catch (const std::exception &e) {
|
||||||
|
Debug() << "Failed to parse" << path << ":" << e.what();
|
||||||
|
}
|
||||||
|
catch (const Exception &e) {
|
||||||
|
Debug() << "Failed to parse" << path << ":" << "Unknown encoding";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret.is_object())
|
||||||
|
ret = json::object({});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#define CONF_FILE "mkxp.json"
|
#define CONF_FILE "mkxp.json"
|
||||||
|
|
||||||
Config::Config() {}
|
Config::Config() {}
|
||||||
|
@ -183,37 +208,43 @@ try { exp } catch (...) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mkxp_fs::fileExists(CONF_FILE)) {
|
json::value baseConf = readConfFile(CONF_FILE);
|
||||||
|
copyObject(optsJ, baseConf);
|
||||||
json::value confData = json::value(0);
|
copyObject(opts["bindingNames"], baseConf.as_object()["bindingNames"], "bindingNames .");
|
||||||
try {
|
|
||||||
std::string cfg = mkxp_fs::contentsOfFileAsString(CONF_FILE);
|
|
||||||
confData = json::parse5(Encoding::convertString(cfg));
|
|
||||||
}
|
|
||||||
catch (const std::exception &e) {
|
|
||||||
Debug() << "Failed to parse JSON configuration:" << e.what();
|
|
||||||
}
|
|
||||||
catch (const Exception &e) {
|
|
||||||
Debug() << "Failed to parse JSON configuration: Unknown encoding";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!confData.is_object())
|
|
||||||
confData = json::object({});
|
|
||||||
|
|
||||||
raw = confData;
|
|
||||||
|
|
||||||
copyObject(optsJ, confData);
|
|
||||||
copyObject(opts["bindingNames"], confData.as_object()["bindingNames"], "bindingNames .");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
raw = json::object({});
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_OPT_CUSTOMKEY(var, key, type) GUARD(var = opts[#key].as_##type();)
|
#define SET_OPT_CUSTOMKEY(var, key, type) GUARD(var = opts[#key].as_##type();)
|
||||||
#define SET_OPT(var, type) SET_OPT_CUSTOMKEY(var, var, type)
|
#define SET_OPT(var, type) SET_OPT_CUSTOMKEY(var, var, type)
|
||||||
#define SET_STRINGOPT(var, key) GUARD(var = std::string(opts[#key].as_string());)
|
#define SET_STRINGOPT(var, key) GUARD(var = std::string(opts[#key].as_string());)
|
||||||
|
|
||||||
|
SET_STRINGOPT(gameFolder, gameFolder);
|
||||||
|
SET_STRINGOPT(dataPathOrg, dataPathOrg);
|
||||||
|
SET_STRINGOPT(dataPathApp, dataPathApp);
|
||||||
|
SET_STRINGOPT(iconPath, iconPath);
|
||||||
|
SET_STRINGOPT(execName, execName);
|
||||||
|
SET_OPT(allowSymlinks, boolean);
|
||||||
|
SET_OPT(pathCache, boolean);
|
||||||
|
SET_OPT_CUSTOMKEY(jit.enabled, JITEnable, boolean);
|
||||||
|
SET_OPT_CUSTOMKEY(jit.verboseLevel, JITVerboseLevel, integer);
|
||||||
|
SET_OPT_CUSTOMKEY(jit.maxCache, JITMaxCache, integer);
|
||||||
|
SET_OPT_CUSTOMKEY(jit.minCalls, JITMinCalls, integer);
|
||||||
SET_OPT(rgssVersion, integer);
|
SET_OPT(rgssVersion, integer);
|
||||||
|
SET_OPT(defScreenW, integer);
|
||||||
|
SET_OPT(defScreenH, integer);
|
||||||
|
|
||||||
|
// Take a break real quick and witch to set game folder and read the game's ini
|
||||||
|
if (!gameFolder.empty() && !mkxp_fs::setCurrentDirectory(gameFolder.c_str())) {
|
||||||
|
throw Exception(Exception::MKXPError, "Unable to switch into gameFolder %s", gameFolder.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
readGameINI();
|
||||||
|
|
||||||
|
// Now check for an extra mkxp.conf in the user's save directory and merge anything else from that
|
||||||
|
std::string userConfPath = customDataPath + "/" CONF_FILE;
|
||||||
|
json::value userConf = readConfFile(userConfPath.c_str());
|
||||||
|
copyObject(optsJ, userConf);
|
||||||
|
|
||||||
|
// now RESUME
|
||||||
|
|
||||||
SET_OPT(debugMode, boolean);
|
SET_OPT(debugMode, boolean);
|
||||||
SET_OPT(printFPS, boolean);
|
SET_OPT(printFPS, boolean);
|
||||||
SET_OPT(fullscreen, boolean);
|
SET_OPT(fullscreen, boolean);
|
||||||
|
@ -221,8 +252,6 @@ try { exp } catch (...) {}
|
||||||
SET_OPT(smoothScaling, boolean);
|
SET_OPT(smoothScaling, boolean);
|
||||||
SET_OPT(winResizable, boolean);
|
SET_OPT(winResizable, boolean);
|
||||||
SET_OPT(vsync, boolean);
|
SET_OPT(vsync, boolean);
|
||||||
SET_OPT(defScreenW, integer);
|
|
||||||
SET_OPT(defScreenH, integer);
|
|
||||||
SET_STRINGOPT(windowTitle, windowTitle);
|
SET_STRINGOPT(windowTitle, windowTitle);
|
||||||
SET_OPT(fixedFramerate, integer);
|
SET_OPT(fixedFramerate, integer);
|
||||||
SET_OPT(frameSkip, boolean);
|
SET_OPT(frameSkip, boolean);
|
||||||
|
@ -233,26 +262,15 @@ try { exp } catch (...) {}
|
||||||
SET_OPT_CUSTOMKEY(integerScaling.active, integerScalingActive, boolean);
|
SET_OPT_CUSTOMKEY(integerScaling.active, integerScalingActive, boolean);
|
||||||
SET_OPT_CUSTOMKEY(integerScaling.lastMileScaling, integerScalingLastMile, boolean);
|
SET_OPT_CUSTOMKEY(integerScaling.lastMileScaling, integerScalingLastMile, boolean);
|
||||||
SET_OPT(maxTextureSize, integer);
|
SET_OPT(maxTextureSize, integer);
|
||||||
SET_STRINGOPT(gameFolder, gameFolder);
|
|
||||||
SET_OPT(anyAltToggleFS, boolean);
|
SET_OPT(anyAltToggleFS, boolean);
|
||||||
SET_OPT(enableReset, boolean);
|
SET_OPT(enableReset, boolean);
|
||||||
SET_OPT(enableSettings, boolean);
|
SET_OPT(enableSettings, boolean);
|
||||||
SET_OPT(allowSymlinks, boolean);
|
|
||||||
SET_STRINGOPT(dataPathOrg, dataPathOrg);
|
|
||||||
SET_STRINGOPT(dataPathApp, dataPathApp);
|
|
||||||
SET_STRINGOPT(iconPath, iconPath);
|
|
||||||
SET_STRINGOPT(execName, execName);
|
|
||||||
SET_STRINGOPT(midi.soundFont, midiSoundFont);
|
SET_STRINGOPT(midi.soundFont, midiSoundFont);
|
||||||
SET_OPT_CUSTOMKEY(midi.chorus, midiChorus, boolean);
|
SET_OPT_CUSTOMKEY(midi.chorus, midiChorus, boolean);
|
||||||
SET_OPT_CUSTOMKEY(midi.reverb, midiReverb, boolean);
|
SET_OPT_CUSTOMKEY(midi.reverb, midiReverb, boolean);
|
||||||
SET_OPT_CUSTOMKEY(SE.sourceCount, SESourceCount, integer);
|
SET_OPT_CUSTOMKEY(SE.sourceCount, SESourceCount, integer);
|
||||||
SET_STRINGOPT(customScript, customScript);
|
SET_STRINGOPT(customScript, customScript);
|
||||||
SET_OPT(pathCache, boolean);
|
|
||||||
SET_OPT(useScriptNames, boolean);
|
SET_OPT(useScriptNames, boolean);
|
||||||
SET_OPT_CUSTOMKEY(jit.enabled, JITEnable, boolean);
|
|
||||||
SET_OPT_CUSTOMKEY(jit.verboseLevel, JITVerboseLevel, integer);
|
|
||||||
SET_OPT_CUSTOMKEY(jit.maxCache, JITMaxCache, integer);
|
|
||||||
SET_OPT_CUSTOMKEY(jit.minCalls, JITMinCalls, integer);
|
|
||||||
|
|
||||||
fillStringVec(opts["preloadScript"], preloadScripts);
|
fillStringVec(opts["preloadScript"], preloadScripts);
|
||||||
fillStringVec(opts["RTP"], rtps);
|
fillStringVec(opts["RTP"], rtps);
|
||||||
|
@ -287,6 +305,8 @@ try { exp } catch (...) {}
|
||||||
// The config is re-read after the window is already created, so some entries
|
// The config is re-read after the window is already created, so some entries
|
||||||
// may not take effect
|
// may not take effect
|
||||||
manualFolderSelect = getEnvironmentBool("MKXPZ_FOLDER_SELECT", false);
|
manualFolderSelect = getEnvironmentBool("MKXPZ_FOLDER_SELECT", false);
|
||||||
|
|
||||||
|
raw = optsJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupScreenSize(Config &conf) {
|
static void setupScreenSize(Config &conf) {
|
||||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -239,16 +239,6 @@ int main(int argc, char *argv[]) {
|
||||||
Config conf;
|
Config conf;
|
||||||
conf.read(argc, argv);
|
conf.read(argc, argv);
|
||||||
|
|
||||||
if (!conf.gameFolder.empty()) {
|
|
||||||
|
|
||||||
if (!mkxp_fs::setCurrentDirectory(conf.gameFolder.c_str()))
|
|
||||||
{
|
|
||||||
showInitError(std::string("Unable to switch into gameFolder ") +
|
|
||||||
conf.gameFolder);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
// Create a debug console in debug mode
|
// Create a debug console in debug mode
|
||||||
if (conf.winConsole) {
|
if (conf.winConsole) {
|
||||||
|
@ -262,7 +252,6 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
conf.readGameINI();
|
|
||||||
|
|
||||||
#ifdef MKXPZ_STEAM
|
#ifdef MKXPZ_STEAM
|
||||||
if (!STEAMSHIM_init()) {
|
if (!STEAMSHIM_init()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue