# HG changeset patch # User Michael Pavone # Date 1556158129 25200 # Node ID a4cae960fd08c74cd7713a05515ce0974825ef4e # Parent 419b458f93cd287b85f519e9aa4e010cae47c13d Allow config file to be saved with executable for "portable" setups diff -r 419b458f93cd -r a4cae960fd08 config.c --- a/config.c Tue Apr 23 23:37:15 2019 -0700 +++ b/config.c Wed Apr 24 19:08:49 2019 -0700 @@ -225,7 +225,7 @@ return ret; } -tern_node *load_overrideable_config(char *name, char *bundled_name) +tern_node *load_overrideable_config(char *name, char *bundled_name, uint8_t *used_config_dir) { char const *confdir = get_config_dir(); char *confpath = NULL; @@ -233,58 +233,60 @@ if (confdir) { confpath = path_append(confdir, name); ret = parse_config_file(confpath); - if (ret) { - free(confpath); - return ret; + } + free(confpath); + if (used_config_dir) { + *used_config_dir = ret != NULL; + } + + if (!ret) { + ret = parse_bundled_config(name); + if (!ret) { + ret = parse_bundled_config(bundled_name); } } - ret = parse_bundled_config(bundled_name); - if (ret) { - free(confpath); - return ret; - } - return NULL; + return ret; } +static uint8_t app_config_in_config_dir; tern_node *load_config() { - char const *confdir = get_config_dir(); - char *confpath = NULL; - tern_node *ret = load_overrideable_config("blastem.cfg", "default.cfg"); - if (confdir) { - confpath = path_append(confdir, "blastem.cfg"); - ret = parse_config_file(confpath); - if (ret) { - free(confpath); - return ret; + tern_node *ret = load_overrideable_config("blastem.cfg", "default.cfg", &app_config_in_config_dir); + + if (!ret) { + if (get_config_dir()) { + fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", get_config_dir()); + } else { + fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n"); } } - - ret = parse_bundled_config("default.cfg"); - if (ret) { - free(confpath); - return ret; - } - - if (get_config_dir()) { - fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", get_config_dir()); - } else { - fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n"); - } - //this will never get reached, but the compiler doesn't know that. Let's make it happy - return NULL; + return ret; } -void persist_config_at(tern_node *config, char *fname) +void persist_config_at(tern_node *app_config, tern_node *to_save, char *fname) { - char const *confdir = get_config_dir(); - if (!confdir) { - fatal_error("Failed to locate config file directory\n"); + char*use_exe_dir = tern_find_path_default(app_config, "ui\0config_in_exe_dir\0", (tern_val){.ptrval = "off"}, TVAL_PTR).ptrval; + char *confpath; + if (!strcmp(use_exe_dir, "on")) { + confpath = path_append(get_exe_dir(), fname); + if (app_config == to_save && app_config_in_config_dir) { + //user switched to "portable" configs this session and there is an + //existing config file in the user-specific config directory + //delete it so we don't end up loading it next time + char *oldpath = path_append(get_config_dir(), fname); + delete_file(oldpath); + free(oldpath); + } + } else { + char const *confdir = get_config_dir(); + if (!confdir) { + fatal_error("Failed to locate config file directory\n"); + } + ensure_dir_exists(confdir); + confpath = path_append(confdir, fname); } - ensure_dir_exists(confdir); - char *confpath = path_append(confdir, fname); - if (!serialize_config_file(config, confpath)) { + if (!serialize_config_file(to_save, confpath)) { fatal_error("Failed to write config to %s\n", confpath); } free(confpath); @@ -292,7 +294,7 @@ void persist_config(tern_node *config) { - persist_config_at(config, "blastem.cfg"); + persist_config_at(config, config, "blastem.cfg"); } char **get_extension_list(tern_node *config, uint32_t *num_exts_out) diff -r 419b458f93cd -r a4cae960fd08 config.h --- a/config.h Tue Apr 23 23:37:15 2019 -0700 +++ b/config.h Wed Apr 24 19:08:49 2019 -0700 @@ -9,11 +9,11 @@ tern_node *parse_config_file(char *config_path); tern_node *parse_bundled_config(char *config_name); -tern_node *load_overrideable_config(char *name, char *bundled_name); +tern_node *load_overrideable_config(char *name, char *bundled_name, uint8_t *used_config_dir); tern_node *load_config(); char *serialize_config(tern_node *config, uint32_t *size_out); uint8_t serialize_config_file(tern_node *config, char *path); -void persist_config_at(tern_node *config, char *fname); +void persist_config_at(tern_node *app_config, tern_node *to_save, char *fname); void persist_config(tern_node *config); char **get_extension_list(tern_node *config, uint32_t *num_exts_out); uint32_t get_lowpass_cutoff(tern_node *config); diff -r 419b458f93cd -r a4cae960fd08 controller_info.c --- a/controller_info.c Tue Apr 23 23:37:15 2019 -0700 +++ b/controller_info.c Wed Apr 24 19:08:49 2019 -0700 @@ -6,6 +6,7 @@ #include "controller_info.h" #include "config.h" #include "util.h" +#include "blastem.h" typedef struct { char const *name; @@ -66,7 +67,7 @@ static void load_ctype_config(void) { if (!loaded) { - info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg"); + info_config = load_overrideable_config("controller_types.cfg", "controller_types.cfg", NULL); loaded = 1; } } @@ -197,7 +198,7 @@ existing = tern_insert_ptr(existing, "subtype", (void *)subtype_names[info->subtype]); existing = tern_insert_ptr(existing, "variant", (void *)variant_names[info->variant]); info_config = tern_insert_node(info_config, guid_string, existing); - persist_config_at(info_config, "controller_types.cfg"); + persist_config_at(config, info_config, "controller_types.cfg"); #endif } @@ -209,7 +210,7 @@ tern_node *existing = tern_find_node(info_config, guid_string); existing = tern_insert_ptr(existing, "mapping", mapping_string); info_config = tern_insert_node(info_config, guid_string, existing); - persist_config_at(info_config, "controller_types.cfg"); + persist_config_at(config, info_config, "controller_types.cfg"); #endif } diff -r 419b458f93cd -r a4cae960fd08 nuklear_ui/blastem_nuklear.c --- a/nuklear_ui/blastem_nuklear.c Tue Apr 23 23:37:15 2019 -0700 +++ b/nuklear_ui/blastem_nuklear.c Wed Apr 24 19:08:49 2019 -0700 @@ -1827,6 +1827,7 @@ selected_sync = settings_dropdown(context, "Sync Source", sync_opts, num_sync_opts, selected_sync, "system\0sync_source\0"); settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); + settings_toggle(context, "Save config with EXE", "ui\0config_in_exe_dir\0", 0); selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0"); diff -r 419b458f93cd -r a4cae960fd08 util.c --- a/util.c Tue Apr 23 23:37:15 2019 -0700 +++ b/util.c Wed Apr 24 19:08:49 2019 -0700 @@ -854,6 +854,16 @@ qsort(list, num_entries, sizeof(dir_entry), sort_dir_alpha); } +uint8_t delete_file(char *path) +{ +#ifdef _WIN32 + //TODO: Call Unicode version and prepend special string to remove max path limitation + return 0 != DeleteFileA(path); +#else + return 0 == unlink(path); +#endif +} + #ifdef __ANDROID__ #include @@ -943,7 +953,7 @@ fclose(f); return ret; } -#endif +#endif //ISLIB #ifdef _WIN32 char const *get_userdata_dir() @@ -1000,8 +1010,6 @@ } -#endif - +#endif //_WIN32 +#endif //__ANDROID__ - -#endif diff -r 419b458f93cd -r a4cae960fd08 util.h --- a/util.h Tue Apr 23 23:37:15 2019 -0700 +++ b/util.h Wed Apr 24 19:08:49 2019 -0700 @@ -88,5 +88,7 @@ void debug_message(char *format, ...); //Disables output of info and debug messages to stdout void disable_stdout_messages(void); +//Deletes a file, returns true on success, false on failure +uint8_t delete_file(char *path); #endif //UTIL_H_