/* /\ +------------------------------------------------------------+ ____/ \____ /| zlib/MIT/Unlicenced game framework licensed to freely use, | \ / / | copy, modify and sell without restriction | +--\ ^__^ /--+ | | | ~/ \~ | | Learn more about [SPACE BOX] at [shampoo.ooo] | | ~~~~~~~~~~~~ | +------------------------------------------------------------+ | SPACE ~~~~~ | / | ~~~~~~~ BOX |/ +-------------*/ #include "Configuration.hpp" /* Initialize a Configuration object. The path argument is the location where the config file is stored. * If there is no file located at the path, it will be created if the write method is called. System level * default assignments defined in this file can be added to and overwritten by user supplied JSON file at * the specified path or at a path passed to the load function. */ Configuration::Configuration(Node *parent, fs::path path) : Node(parent) { config_path = path; set_defaults(); load(); auto_refresher.set_frame_length(config["configuration"]["auto-refresh-interval"].get()); auto_refresh(config["configuration"]["auto-refresh"]); } /* Fill the system level config JSON dict with default values set by the framework */ void Configuration::set_defaults() { sys_config["keys"] = { {"record", {"CTRL", "SHIFT", "i"}}, {"save-current-stash", {"CTRL", "SHIFT", "v"}}, {"screenshot", {"CTRL", "i"}}, {"action", "space"}, {"up", "up"}, {"right", "right"}, {"down", "down"}, {"left", "left"}, {"pause", "enter"}, {"fullscreen", {"ALT", "enter"}}, {"toggle-framerate", {"CTRL", "f"}}, {"reset", {"CTRL", "r"}} }; sys_config["input"] = { {"suppress-any-key-on-mods", true}, {"system-any-key-ignore-commands", {"fullscreen", "screenshot", "toggle-framerate", "record", "quit"}}, {"any-key-ignore-commands", nlohmann::json::array()}, {"default-unsuppress-delay", 700}, {"ignore-repeat-keypress", true} }; sys_config["display"] = { {"dimensions", {960, 540}}, {"framerate", 60}, {"title", "[SPACEBOX]"}, {"debug", false}, {"show-cursor", false}, {"render-test-spacing", 2}, {"render driver", "opengl"} }; sys_config["audio"] = { {"default-sfx-root", "resource/sfx"}, {"default-bgm-root", "resource/bgm"} }; sys_config["gl"] = { {"depth-size", 16}, {"red-size", 8}, {"green-size", 8}, {"blue-size", 8}, {"share-with-current-context", true}, {"double-buffer", true}, {"major-version", 3}, {"minor-version", 2} }, sys_config["recording"] = { {"enabled", false}, {"screenshot-prefix", "screenshot-"}, {"screenshot-extension", ".png"}, {"screenshot-zfill", 5}, {"screenshot-directory", "."}, {"gif-frame-length", 100}, {"video-directory", "."}, {"write-mp4", false}, {"max-stash-length", 5000}, {"max-in-game-stashes", 3}, {"max-video-stashes", 40}, {"max-video-memory", 1000}, {"mp4-pixel-format", "yuv444p"} }; sys_config["fps-indicator"] = { {"width", .05}, {"height", .04}, {"background", {255, 255, 255}}, {"foreground", {0, 0, 0}} }; sys_config["animation"] = { {"all-frames-frameset-name", "all"} }; sys_config["log"] = { {"enabled", false}, {"debug-to-stdout", false}, {"debug-to-file", false}, {"output-directory", "."}, {"info-file-name", "space_box_log.txt"}, {"debug-file-name", "space_box_debug_log.txt"}, {"short-name", "spacebox"} }; sys_config["configuration"] = { {"auto-refresh", false}, {"auto-refresh-interval", 1000} }; config = sys_config; } /* Load the configuration file at path */ void Configuration::load(fs::path path) { /* read contents of path into the game level config JSON dict */ user_config = nlohmann::json::parse(sb::file_to_string(path)); /* merge into the full config JSON dict */ merge(); } /* Load the configuration file at Configuration::config_path */ void Configuration::load() { load(config_path); } /* Merge the system level config JSON dict (hard-coded in this file) with the user level config JSON * dict (loaded from disk by the load function) */ void Configuration::merge() { if (!user_config.empty()) { /* loop over first level key/value pairs */ for (auto& item: user_config.items()) { /* if the value is an object (dict), merge it into the config, overwriting keys already in the config */ if (item.value().is_object()) { config[item.key()].update(item.value()); } /* otherwise just assign config key to this value */ else { config[item.key()] = item.value(); } } } } /* Set auto refresh to on or off */ void Configuration::auto_refresh(bool on) { on ? auto_refresher.play() : auto_refresher.pause(); } /* Refresh the config contents by calling the default load function */ void Configuration::refresh() { if (fs::exists(config_path) && fs::last_write_time(config_path) > config_file_modification_time) { std::ostringstream message; message << "config file modified, reloading " << config_path; sb::Log::log(message, sb::Log::DEBUG); load(); } } /* Write configuration to specified path in JSON format */ void Configuration::write(fs::path path) { std::ofstream output(path); output << std::setw(tab_width) << user_config << std::endl; } /* Write configuration to config_path (set at initialization) */ void Configuration::write() { write(config_path); } /* Updates the auto refresher */ void Configuration::update() { auto_refresher.update(); }