From f6e35420bc7a464b60764add1fe143f09b391b91 Mon Sep 17 00:00:00 2001 From: HyperspaceMadness Date: Mon, 2 Nov 2020 21:07:20 -0500 Subject: [PATCH] Simple Shader Save Cleanup --- gfx/video_shader_parse.c | 295 +++++++++++++++-------------- libretro-common/file/config_file.c | 71 ++++--- menu/cbs/menu_cbs_sublabel.c | 4 + msg_hash.h | 2 +- 4 files changed, 200 insertions(+), 172 deletions(-) diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 60c495a658..302feea5d2 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -603,19 +603,20 @@ bool video_shader_write_referenced_preset(const char *path, const struct video_shader *shader) { unsigned i; - bool ret = false; - bool continue_saving_reference = true; - char preset_dir[PATH_MAX_LENGTH]; - config_file_t *conf; - char *absolute_root_preset_path = (char*)malloc(PATH_MAX_LENGTH); - char *absolute_new_preset_basedir = (char*)malloc(PATH_MAX_LENGTH); - char *relative_root_preset_path = (char*)malloc(PATH_MAX_LENGTH); + config_file_t *conf = NULL; + bool ret = false; + bool continue_saving_reference = true; + char *preset_dir = (char*)malloc(PATH_MAX_LENGTH); + char *absolute_root_preset_path = (char*)malloc(PATH_MAX_LENGTH); + char *relative_root_preset_path = (char*)malloc(PATH_MAX_LENGTH); + char *absolute_new_preset_basedir = NULL; - preset_dir[0] = '\0'; - absolute_new_preset_basedir = strdup(path); - path_basedir(absolute_new_preset_basedir); + preset_dir[0] = '\0'; absolute_root_preset_path[0] = '\0'; relative_root_preset_path[0] = '\0'; + absolute_new_preset_basedir = strdup(path); + + path_basedir(absolute_new_preset_basedir); /* Get the absolute path to the root preset, this is the one which is used in the #reference directive */ strlcpy(absolute_root_preset_path, shader->path, PATH_MAX_LENGTH); @@ -634,21 +635,6 @@ bool video_shader_write_referenced_preset(const char *path, continue_saving_reference = false; } - /* Auto-shaders can be written as copies or references. - * If we write a reference to a copy, we could then overwrite the copy - * with any reference, thus creating a reference to a reference. - * To prevent this, we disallow saving references to auto-shaders. */ - fill_pathname_join(preset_dir, - shader_dir, - "presets", - sizeof(preset_dir)); - if (continue_saving_reference && !strncmp(preset_dir, absolute_root_preset_path, strlen(preset_dir))) - { - RARCH_WARN("[Shaders-Save Reference]: Saving Full Preset because we can't save a " - "reference to an auto-loaded shader (E.G. Game Preset, Core Preset).\n"); - continue_saving_reference = false; - } - /* Don't ever create a reference to the ever-changing retroarch preset * TODO remove once we don't write this preset anymore */ if (continue_saving_reference && !strncmp(path_basename(absolute_root_preset_path), "retroarch", STRLEN_CONST("retroarch"))) @@ -674,7 +660,7 @@ bool video_shader_write_referenced_preset(const char *path, /* Create a new EMPTY config */ conf = config_file_new_alloc(); if (!(conf)) - return false; + goto end; conf->path = strdup(path); /* Add the reference path to the config */ @@ -879,21 +865,18 @@ bool video_shader_write_referenced_preset(const char *path, /* If the shader has textures */ if (shader->luts) { - char *shader_tex_path = (char*)malloc(3*PATH_MAX_LENGTH); - char *shader_tex_relative_path = shader_tex_path + PATH_MAX_LENGTH; - char *shader_tex_base_path = shader_tex_path + 2*PATH_MAX_LENGTH; - char *referenced_tex_absolute_path = (char*)malloc(PATH_MAX_LENGTH); - char *referenced_tex_path = (char*)malloc(PATH_MAX_LENGTH); - size_t tex_size = 4096 * sizeof(char); - char *textures = (char*)malloc(tex_size); + char *shader_tex_path = (char*)malloc(PATH_MAX_LENGTH); + char *shader_tex_relative_path = (char*)malloc(PATH_MAX_LENGTH); + char *shader_tex_base_path = (char*)malloc(PATH_MAX_LENGTH); + char *referenced_tex_absolute_path = (char*)malloc(PATH_MAX_LENGTH); + char *referenced_tex_path = (char*)malloc(PATH_MAX_LENGTH); unsigned i; - shader_tex_path[0] = '\0'; - shader_tex_relative_path[0] = '\0'; - shader_tex_base_path[0] = '\0'; - textures[0] = '\0'; + shader_tex_path[0] = '\0'; + shader_tex_relative_path[0] = '\0'; + shader_tex_base_path[0] = '\0'; referenced_tex_absolute_path[0] = '\0'; - referenced_tex_path[0] = '\0'; + referenced_tex_path[0] = '\0'; for (i = 0; i < shader->luts; i++) { @@ -928,6 +911,12 @@ bool video_shader_write_referenced_preset(const char *path, } } } + + free(shader_tex_path); + free(shader_tex_relative_path); + free(shader_tex_base_path); + free(referenced_tex_absolute_path); + free(referenced_tex_path); } /* Write the file, return will be true if successful */ ret = config_file_write(conf, path, false); @@ -937,10 +926,18 @@ bool video_shader_write_referenced_preset(const char *path, "Full Preset Will be Saved instead of Simple Preset\n", path); } config_file_free(root_conf); + free(root_shader); } config_file_free(conf); } + +end: + + free(preset_dir); + free(absolute_root_preset_path); free(relative_root_preset_path); + free(absolute_new_preset_basedir); + return ret; } @@ -1009,123 +1006,139 @@ bool video_shader_write_preset(const char *path, **/ bool override_config_values(config_file_t *conf, config_file_t *override_conf) { - int return_val = 0; - size_t param_size = 4096 * sizeof(char); - const char *id = NULL; - char *save = NULL; - size_t path_size = PATH_MAX_LENGTH; - char *override_texture_path = (char*)malloc(path_size); - char *resolved_path = (char*)malloc(path_size); - char *textures_in_conf = (char*)malloc(param_size); - size_t tmp_size = PATH_MAX_LENGTH; - char *tmp = (char*)malloc(3*tmp_size); - char *tmp_rel = tmp + tmp_size; - char *tmp_base = tmp + 2*tmp_size; - struct config_entry_list *override_entry = NULL; - char *override_parameters = (char*)malloc(param_size); + int return_val = 0; + size_t param_size = 4096 * sizeof(char); + const char *id = NULL; + char *save = NULL; + size_t path_size = PATH_MAX_LENGTH; + char *override_texture_path = (char*)malloc(path_size); + char *resolved_path = (char*)malloc(path_size); + char *textures_in_conf = (char*)malloc(param_size); + size_t tmp_size = PATH_MAX_LENGTH; + char *tmp = (char*)malloc(3*tmp_size); + char *tmp_rel = tmp + tmp_size; + char *tmp_base = tmp + 2*tmp_size; + struct config_entry_list *override_entry = NULL; + char *override_parameters = (char*)malloc(param_size); - override_parameters[0] = '\0'; - textures_in_conf[0] = '\0'; - strlcpy(tmp_base, conf->path, tmp_size); + override_parameters[0] = '\0'; + textures_in_conf[0] = '\0'; + strlcpy(tmp_base, conf->path, tmp_size); - if (conf == NULL || override_conf == NULL) return 0; + if (conf == NULL || override_conf == NULL) return 0; - /* --------------------------------------------------------------------------------- - * ------------- Resolve Override texture paths to absolute paths------------------- - * --------------------------------------------------------------------------------- */ + /* --------------------------------------------------------------------------------- + * ------------- Resolve Override texture paths to absolute paths------------------- + * --------------------------------------------------------------------------------- */ - /* ensure we use a clean base like the shader passes and texture paths do */ - path_resolve_realpath(tmp_base, tmp_size, false); - path_basedir(tmp_base); + /* ensure we use a clean base like the shader passes and texture paths do */ + path_resolve_realpath(tmp_base, tmp_size, false); + path_basedir(tmp_base); - /* If there are textures in the referenced config */ - if (config_get_array(conf, "textures", textures_in_conf, param_size)) + /* If there are textures in the referenced config */ + if (config_get_array(conf, "textures", textures_in_conf, param_size)) + { + for ( id = strtok_r(textures_in_conf, ";", &save); + id; + id = strtok_r(NULL, ";", &save)) { - for ( id = strtok_r(textures_in_conf, ";", &save); - id; - id = strtok_r(NULL, ";", &save)) + /* Get the texture path from the override config */ + if (config_get_path(override_conf, id, override_texture_path, path_size)) { - /* Get the texture path from the override config */ - if (config_get_path(override_conf, id, override_texture_path, path_size)) - { - /* Resolve the texture's path relative to the override config */ - if (!path_is_absolute(override_texture_path)) - fill_pathname_resolve_relative(resolved_path, - override_conf->path, - override_texture_path, - PATH_MAX_LENGTH); - else - strlcpy(resolved_path, override_texture_path, path_size); + /* Resolve the texture's path relative to the override config */ + if (!path_is_absolute(override_texture_path)) + fill_pathname_resolve_relative(resolved_path, + override_conf->path, + override_texture_path, + PATH_MAX_LENGTH); + else + strlcpy(resolved_path, override_texture_path, path_size); - path_relative_to(tmp_rel, resolved_path, tmp_base, tmp_size); - config_set_path(override_conf, id, tmp_rel); + path_relative_to(tmp_rel, resolved_path, tmp_base, tmp_size); + config_set_path(override_conf, id, tmp_rel); - return_val = 1; - } - } - } - - /* --------------------------------------------------------------------------------- - * -------------Update Parameter List to include Override Parameters---------------- - * --------------------------------------------------------------------------------- */ - - /* If there is a 'parameters' entry in the override config we want to add these parameters - * to the referenced config if they are not already there */ - if (config_get_array(override_conf, "parameters", override_parameters, param_size)) - { - /* Get the string for the parameters from the root config */ - char *parameters = NULL; - parameters = (char*)malloc(param_size); - parameters[0] = '\0'; - - /* If there are is no parameters entry in the root config, add one */ - if (!config_get_array(conf, "parameters", parameters, param_size)) - { - config_set_string(conf, "parameters", ""); - config_get_array(conf, "parameters", parameters, param_size); - } - - /* Step through each parameter in override config */ - for ( id = strtok_r(override_parameters, ";", &save); - id; - id = strtok_r(NULL, ";", &save)) - { - /* If the parameter is not in the root config's parameter list add it */ - if (!strstr(parameters, id)) - { - strlcat(parameters, ";", param_size); - strlcat(parameters, id, param_size); - return_val = 1; - } - } - config_set_string(conf, "parameters", strdup(parameters)); - - free(parameters); - } - - /* --------------------------------------------------------------------------------- - * ------------- Update entries to match the override entries ---------------------- - * --------------------------------------------------------------------------------- */ - - for (override_entry = override_conf->entries; override_entry; override_entry = override_entry->next) - { - /* Only override an entry if the it's key is not "parameters", and not in list of textures */ - if (!string_is_empty(override_entry->key) && !string_is_equal(override_entry->key, "parameters") && !string_is_equal(override_entry->key, "textures")) - { - RARCH_LOG("[Shaders-Load Reference]: Entry overridden %s = %s.\n", - override_entry->key, override_entry->value); - config_set_string(conf, override_entry->key, strdup(override_entry->value)); return_val = 1; } } + } - free(tmp); - free(resolved_path); - free(override_texture_path); - free(override_parameters); - free(textures_in_conf); + /* --------------------------------------------------------------------------------- + * -------------Update Parameter List to include Override Parameters---------------- + * --------------------------------------------------------------------------------- */ - return return_val; + /* If there is a 'parameters' entry in the override config we want to add these parameters + * to the referenced config if they are not already there */ + if (config_get_array(override_conf, "parameters", override_parameters, param_size)) + { + /* Get the string for the parameters from the root config */ + char *parameters = NULL; + const char *override_id = NULL; + char *override_save = NULL; + bool param_found = false; + + parameters = (char*)malloc(param_size); + parameters[0] = '\0'; + + /* If there are is no parameters entry in the root config, add one */ + if (!config_get_array(conf, "parameters", parameters, param_size)) + { + config_set_string(conf, "parameters", ""); + config_get_array(conf, "parameters", parameters, param_size); + } + + /* Step through each parameter in override config */ + for ( override_id = strtok_r(override_parameters, ";", &override_save); + override_id; + override_id = strtok_r(NULL, ";", &override_save)) + { + /* Check all ids in the parameters array to see if the + * override id is already there */ + for ( id = strtok_r(parameters, ";", &save); + id; + id = strtok_r(NULL, ";", &save)) + if (string_is_equal(id, override_id)) + { + param_found = true; + break; + } + + /* If the parameter is not in the config's parameter list yet add it */ + if (!param_found) + { + strlcat(parameters, ";", param_size); + strlcat(parameters, override_id, param_size); + return_val = 1; + } + param_found = false; + } + config_set_string(conf, "parameters", parameters); + + free(parameters); + } + + /* --------------------------------------------------------------------------------- + * ------------- Update entries to match the override entries ---------------------- + * --------------------------------------------------------------------------------- */ + + for (override_entry = override_conf->entries; override_entry; override_entry = override_entry->next) + { + /* Only override an entry if the it's key is not "parameters", and not in list of textures */ + if (!string_is_empty(override_entry->key) && !string_is_equal(override_entry->key, "parameters") && !string_is_equal(override_entry->key, "textures")) + { + RARCH_LOG("[Shaders-Load Reference]: Entry overridden %s = %s.\n", + override_entry->key, override_entry->value); + config_set_string(conf, override_entry->key, override_entry->value); + return_val = 1; + } + } + + free(tmp); + free(resolved_path); + free(override_texture_path); + free(override_parameters); + free(textures_in_conf); + + return return_val; } /** diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 37438fc517..49547f4682 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -181,7 +181,7 @@ static char *config_file_strip_comment(char *str) *str = '\0'; return ++comment; } - + /* Comment character occurs at an offset: * Search for the start of a string literal value */ literal_start = strchr(str, '\"'); @@ -463,24 +463,26 @@ static bool config_file_parse_line(config_file_t *conf, if (comment) { config_file_t sub_conf; + bool include_found = false; + bool reference_found = false; char real_path[PATH_MAX_LENGTH]; char *path = NULL; char *include_line = NULL; char *reference_line = NULL; - /* Starting a line with an 'include' directive - * appends a sub-config file - * > All other comments are ignored */ - if (!string_starts_with_size(comment, "include ", - STRLEN_CONST("include ")) && - !string_starts_with_size(comment, "reference ", - STRLEN_CONST("reference "))) + include_found = string_starts_with_size(comment, "include ", + STRLEN_CONST("include ")); + reference_found = string_starts_with_size(comment, "reference ", + STRLEN_CONST("reference ")); + + /* All comments except those starting with the include or + * reference directive are ignored */ + if (!include_found && !reference_found) return false; /* Starting a line with an 'include' directive * appends a sub-config file */ - if (string_starts_with_size(comment, "include ", - STRLEN_CONST("include "))) + if (include_found) { include_line = comment + STRLEN_CONST("include "); @@ -492,8 +494,8 @@ static bool config_file_parse_line(config_file_t *conf, if (!path) return false; - if ( string_is_empty(path) - || conf->include_depth >= MAX_INCLUDE_DEPTH) + if ( string_is_empty(path) + || conf->include_depth >= MAX_INCLUDE_DEPTH) { free(path); return false; @@ -508,22 +510,22 @@ static bool config_file_parse_line(config_file_t *conf, switch (config_file_load_internal(&sub_conf, real_path, conf->include_depth + 1, cb)) { - case 0: - /* Pilfer internal list. */ - config_file_add_child_list(conf, &sub_conf); - /* fall-through to deinitialize */ - case -1: - config_file_deinitialize(&sub_conf); - break; - case 1: - default: - break; + case 0: + /* Pilfer internal list. */ + config_file_add_child_list(conf, &sub_conf); + /* fall-through to deinitialize */ + case -1: + config_file_deinitialize(&sub_conf); + break; + case 1: + default: + break; } } - /* If it's a 'reference' directive */ - if (string_starts_with_size(comment, "reference ", - STRLEN_CONST("reference "))) + /* Starting a line with an 'reference' directive + * sets the reference path */ + if (reference_found) { reference_line = comment + STRLEN_CONST("reference "); @@ -648,13 +650,19 @@ static int config_file_from_string_internal( void config_file_set_reference_path(config_file_t *conf, char *path) { - if (conf) + /* If a relative path the input path is desired the caller is + * responsible for preparing and supplying the relative path*/ + if (!conf) + return; + + if (conf->reference) { - /* Assumes if you wanted a relative path the input path is - * already relative to the config - */ - conf->reference = strdup(path); + free(conf->reference); + conf->reference = NULL; } + + + conf->reference = strdup(path); } bool config_file_deinitialize(config_file_t *conf) @@ -695,6 +703,9 @@ bool config_file_deinitialize(config_file_t *conf) free(hold); } + if (conf->reference) + free(conf->reference); + if (conf->path) free(conf->path); return true; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 7e0d9f78bf..9e7c35b1e8 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -799,6 +799,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_num_passes, DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_save, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_remove, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_REMOVE) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_save_reference, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_REFERENCE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_save_as, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_save_global, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GLOBAL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_shader_preset_save_core, MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE) @@ -1864,6 +1865,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_REMOVE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_preset_remove); break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_REFERENCE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_preset_save_reference); + break; case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_SAVE_AS: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_shader_preset_save_as); break; diff --git a/msg_hash.h b/msg_hash.h index 1e1f29b79c..8e8af18c1d 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -579,7 +579,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_NORD, MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_GRUVBOX_DARK, MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_BOYSENBERRY, - MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_HACKING_THE_KERNEL, + MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_HACKING_THE_KERNEL, MENU_ENUM_LABEL_VALUE_OZONE_COLOR_THEME_TWILIGHT_ZONE, MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME,