diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index cf552a5348..a0a691dea3 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -99,39 +99,6 @@ static void fill_pathname_expanded_and_absolute(char *out_path, pathname_conform_slashes_to_os(out_path); } -static void gather_reference_path_list(struct path_linked_list *in_path_linked_list, - char *path, - int reference_depth) -{ - config_file_t *conf = NULL; - struct path_linked_list *reference_tmp = NULL; - - if (reference_depth > SHADER_MAX_REFERENCE_DEPTH) - return; - - conf = config_file_new_from_path_to_string(path); - if (conf) - { - reference_tmp = (struct path_linked_list*)conf->references; - while (reference_tmp) - { - char* reference_preset_path = (char*)malloc(PATH_MAX_LENGTH); - - fill_pathname_expanded_and_absolute(reference_preset_path, conf->path, reference_tmp->path); - gather_reference_path_list(in_path_linked_list, reference_preset_path, reference_depth + 1); - - free(reference_preset_path); - reference_tmp = reference_tmp->next; - } - path_linked_list_add_path(in_path_linked_list, path); - } - else - { - RARCH_WARN("\n [Shaders]: No Preset located at \"%s\".\n", path); - } - config_file_free(conf); -} - /** * wrap_mode_to_str: * @type : Wrap type. @@ -884,17 +851,6 @@ end: return ret; } -/* Check if the config is a valid shader chain config */ -static bool video_shader_is_shader_chain_config(config_file_t *conf) -{ - /* If the config has a shaders entry then it is considered - a shader chain config, vs a config which may only have - parameter values and texture overrides - */ - - return config_get_entry(conf, "shaders"); -} - static config_file_t *video_shader_get_root_preset_config(const char *path) { int reference_depth = 1; @@ -907,7 +863,7 @@ static config_file_t *video_shader_get_root_preset_config(const char *path) return NULL; } - while (conf->references) + while (conf->reference) { /* If we have reached the max depth of nested references, * stop attempting to read the next reference, @@ -926,7 +882,7 @@ static config_file_t *video_shader_get_root_preset_config(const char *path) } /* Get the absolute path for the reference */ - fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->references->path); + fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->reference); /* Create a new config from the referenced path */ config_file_free(conf); @@ -944,7 +900,6 @@ static config_file_t *video_shader_get_root_preset_config(const char *path) } free(nested_reference_path); - return conf; } @@ -995,7 +950,7 @@ static bool video_shader_check_reference_chain_for_save( { int reference_depth = 1; - while (conf->references) + while (conf->reference) { /* If we have reached the max depth of nested references stop attempting to read * the next reference because we are likely in a self referential loop. */ @@ -1008,7 +963,7 @@ static bool video_shader_check_reference_chain_for_save( } /* Get the absolute path for the reference */ - fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->references->path); + fill_pathname_expanded_and_absolute(nested_reference_path, conf->path, conf->reference); /* If one of the reference paths is the same as the file we want to save then this reference chain would be * self-referential / cyclical and we can't save this as a simple preset*/ @@ -1151,11 +1106,11 @@ static bool video_shader_write_referenced_preset( * If there is a reference in the initially loaded preset, * we should check it against the preset path we are currently * trying to save */ - if (reference_conf->references) + if (reference_conf->reference) { /* Get the absolute path for the reference */ fill_pathname_expanded_and_absolute(abs_temp_reference_path, - reference_conf->path, reference_conf->references->path); + reference_conf->path, reference_conf->reference); pathname_conform_slashes_to_os(abs_temp_reference_path); @@ -1187,16 +1142,16 @@ static bool video_shader_write_referenced_preset( /* If the reference path is the same as the path we want to save * or the reference path is in the config (auto shader) folder */ - if (string_is_equal(path_to_reference, path_to_save_conformed) + if ( string_is_equal(path_to_reference, path_to_save_conformed) || !strncmp(config_dir, path_to_reference, strlen(config_dir))) { /* If the config from the reference path has a reference in it, * we will use this same nested reference for the new preset */ - if (reference_conf->references) + if (reference_conf->reference) { /* Get the absolute path for the reference */ fill_pathname_expanded_and_absolute(path_to_reference, - reference_conf->path, reference_conf->references->path); + reference_conf->path, reference_conf->reference); /* If the reference path is also the same as what * we are trying to save @@ -1213,11 +1168,11 @@ static bool video_shader_write_referenced_preset( path_to_reference); /* If the reference also has a reference inside it */ - if (reference_conf->references) + if (reference_conf->reference) { /* Get the absolute path for the reference */ fill_pathname_expanded_and_absolute(path_to_reference, - reference_conf->path, reference_conf->references->path); + reference_conf->path, reference_conf->reference); } /* If the config referenced is a full preset */ else @@ -1277,7 +1232,7 @@ static bool video_shader_write_referenced_preset( pathname_make_slashes_portable(relative_temp_reference_path); /* Add the reference path to the config */ - config_file_add_reference(conf, path_to_reference); + config_file_set_reference_path(conf, path_to_reference); /* Set modified to true so when you run config_file_write * it will save a file */ @@ -1760,7 +1715,6 @@ bool video_shader_write_preset(const char *path, } - /** * video_shader_load_preset_into_shader: * @path : Path to preset file, could be a @@ -1777,124 +1731,117 @@ bool video_shader_load_preset_into_shader(const char *path, { unsigned i = 0; bool ret = true; + char override_conf_paths[SHADER_MAX_REFERENCE_DEPTH][PATH_MAX_LENGTH]; config_file_t *conf = NULL; - config_file_t *root_conf = video_shader_get_root_preset_config(path); - struct path_linked_list* override_paths_list = NULL; - struct path_linked_list* path_list_tmp = NULL; + /* Get the root config, If we were able to get a root_config + * that means the reference chain is valid */ + config_file_t *root_conf = + video_shader_get_root_preset_config(path); if (!root_conf) { +#ifdef DEBUG RARCH_LOG("\n"); RARCH_WARN("[Shaders]: Could not read root preset: \"%s\".\n", path); +#endif ret = false; goto end; } - /* Check if the root preset is a valid shader chain */ - if (!video_shader_is_shader_chain_config(root_conf)) - { - RARCH_LOG("\n"); - RARCH_WARN("[Shaders]: Root preset is not a valid shader chain because it has no shaders entry: \"%s\".\n", path); - ret = false; - goto end; - } + /* If we were able to get a root_config that means that the + * whole reference chain is valid */ +#ifdef DEBUG + RARCH_DBG("\n"); +#endif - /* If the root_conf path matches the original path then - * there are no references so we just load it and go to the end */ + video_shader_load_root_config_into_shader(root_conf, + config_get_ptr(), shader); + /* If the root_conf path matches the original path then + * there are no references so we just load it and go to the end */ if (string_is_equal(root_conf->path, path)) - { - /* Load the config from the shader chain from the first reference into the shader */ - video_shader_load_root_config_into_shader(root_conf, config_get_ptr(), shader); goto end; - } /* Get the config from the initial preset file * We don't need to check it's validity because it must * have been valid to get the root preset */ conf = config_file_new_from_path_to_string(path); + /* Set all override_conf_paths to empty so we know which + * ones have been filled */ + for (i = 0; i < SHADER_MAX_REFERENCE_DEPTH; i++) + override_conf_paths[i][0] = '\0'; + + i = 0; + #ifdef DEBUG - RARCH_DBG("\n[Shaders]: Crawl preset reference chain..\n"); + RARCH_DBG("\n"); + RARCH_DBG("[Shaders]: Crawl preset reference chain..\n"); #endif - /** - * Check references starting with the second to make sure - * they do not have a shader chains in them - **/ - path_list_tmp = (struct path_linked_list*)conf->references->next; - while (path_list_tmp) + /* If the config has a reference then we need gather all presets from the + * chain of references to apply their values later */ + while (conf->reference) { - config_file_t *tmp_conf = NULL; - char *path_to_reference = (char*)malloc(PATH_MAX_LENGTH); + char* reference_preset_path = (char*)malloc(PATH_MAX_LENGTH); + i++; - fill_pathname_expanded_and_absolute(path_to_reference, conf->path, path_list_tmp->path); +#ifdef DEBUG + RARCH_DBG("[Shaders]: Preset (depth %u): \"%s\".\n", i, conf->path); +#endif - tmp_conf = video_shader_get_root_preset_config(path_to_reference); - if (tmp_conf) - { - if (video_shader_is_shader_chain_config(tmp_conf)) - { - RARCH_WARN("\n[Shaders]: Additional #reference entries pointing at shader chain presets are not supported: \"%s\".\n", path_to_reference); - config_file_free(tmp_conf); - ret = false; - goto end; - } - else - { - config_file_free(tmp_conf); - } - } - else - { - RARCH_WARN("\n[Shaders]: Could not load root preset for #reference entry: \"%s\".\n", path_to_reference); - ret = false; - goto end; - } - path_list_tmp = path_list_tmp->next; + /* Add the reference to the list */ + strlcpy(override_conf_paths[i], conf->path, PATH_MAX_LENGTH); + + /* Get the absolute path for the reference */ + fill_pathname_expanded_and_absolute(reference_preset_path, + conf->path, conf->reference); + +#ifdef DEBUG + RARCH_DBG("[Shaders]: #reference = \"%s\".\n", + reference_preset_path); +#endif + + /* Create a new config from this reference level */ + config_file_free(conf); + conf = config_file_new_from_path_to_string(reference_preset_path); + + free(reference_preset_path); } - - /* Load the config from the shader chain from the first reference into the shader */ - video_shader_load_root_config_into_shader(root_conf, config_get_ptr(), shader); - - /* Set Path for originally loaded preset because it is different than the root preset path */ - strlcpy(shader->loaded_preset_path, path, sizeof(shader->loaded_preset_path)); - + + /* Step back through the references starting with the one + * referencing the root config and apply overrides for each one */ #ifdef DEBUG - RARCH_DBG("\n[Shaders]: Start applying simple preset overrides..\n"); + RARCH_DBG("\n"); + RARCH_DBG("[Shaders]: Start applying simple preset overrides..\n"); #endif - /* Gather all the paths of all of the presets in all reference chains */ - override_paths_list = path_linked_list_new(); - gather_reference_path_list(override_paths_list, conf->path, 0); - - /* - * Step through the references and apply overrides for each one - * Start on the second item since the first is empty - */ - path_list_tmp = (struct path_linked_list*)override_paths_list; - while (path_list_tmp) + while (i) { - config_file_t *override_conf = NULL; - - override_conf = config_file_new_from_path_to_string(path_list_tmp->path); + config_file_t *override_conf = config_file_new_from_path_to_string( + override_conf_paths[i]); #ifdef DEBUG RARCH_DBG("[Shaders]: Depth %u apply overrides..\n", i); - RARCH_DBG("[Shaders]: Apply values from: \"%s\".\n", override_conf->path); + RARCH_DBG("[Shaders]: Apply values from: \"%s\".\n", + override_conf->path); #endif - override_shader_values(override_conf, shader); + config_file_free(override_conf); - path_list_tmp = path_list_tmp->next; + i--; } - + #ifdef DEBUG - RARCH_DBG("[Shaders]: End apply overrides.\n\n"); + RARCH_DBG("[Shaders]: End apply overrides.\n"); + RARCH_DBG("\n"); #endif + /* Set Path for originally loaded preset because it is + * different than the root preset path */ + strlcpy( shader->loaded_preset_path, path, + sizeof(shader->loaded_preset_path)); end: - path_linked_list_free(override_paths_list); config_file_free(conf); config_file_free(root_conf); diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index de9da1f9f2..507091a815 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -39,6 +39,12 @@ #define MAX_INCLUDE_DEPTH 16 +struct config_include_list +{ + char *path; + struct config_include_list *next; +}; + /* Forward declaration */ static bool config_file_parse_line(config_file_t *conf, struct config_entry_list *list, char *line, config_file_cb_t *cb); @@ -377,26 +383,29 @@ static void config_file_get_realpath(char *s, size_t len, static void config_file_add_sub_conf(config_file_t *conf, char *path, char *real_path, size_t len, config_file_cb_t *cb) { - if (!conf->includes) - conf->includes = path_linked_list_new(); + struct config_include_list *head = conf->includes; + struct config_include_list *node = (struct config_include_list*) + malloc(sizeof(*node)); - path_linked_list_add_path(conf->includes, path); + if (node) + { + node->next = NULL; + /* Add include list */ + node->path = strdup(path); - config_file_get_realpath(real_path, len, path, conf->path); -} + if (head) + { + while (head->next) + head = head->next; -void config_file_add_reference(config_file_t *conf, char *path) -{ - /* It is expected that the conf has it's path already set */ - char short_path[PATH_MAX_LENGTH]; - - short_path[0] = '\0'; - - if (!conf->references) - conf->references = path_linked_list_new(); + head->next = node; + } + else + conf->includes = node; + } - fill_pathname_abbreviated_or_relative(short_path, conf->path, path, sizeof(short_path)); - path_linked_list_add_path(conf->references, short_path); + config_file_get_realpath(real_path, len, path, + conf->path); } static int config_file_load_internal( @@ -572,7 +581,7 @@ static bool config_file_parse_line(config_file_t *conf, if (!path) return false; - config_file_add_reference(conf, path); + config_file_set_reference_path(conf, path); if (!path) return false; @@ -693,11 +702,31 @@ static int config_file_from_string_internal( return 0; } +void config_file_set_reference_path(config_file_t *conf, char *path) +{ + /* It is expected that the conf has it's path already set */ + + char short_path[PATH_MAX_LENGTH]; + + short_path[0] = '\0'; + + if (!conf) + return; + + if (conf->reference) + { + free(conf->reference); + conf->reference = NULL; + } + + fill_pathname_abbreviated_or_relative(short_path, conf->path, path, sizeof(short_path)); + + conf->reference = strdup(short_path); +} bool config_file_deinitialize(config_file_t *conf) { - struct path_linked_list *inc_tmp = NULL; - struct path_linked_list *ref_tmp = NULL; + struct config_include_list *inc_tmp = NULL; struct config_entry_list *tmp = NULL; if (!conf) return false; @@ -721,8 +750,20 @@ bool config_file_deinitialize(config_file_t *conf) free(hold); } - path_linked_list_free(conf->includes); - path_linked_list_free(conf->references); + inc_tmp = (struct config_include_list*)conf->includes; + while (inc_tmp) + { + struct config_include_list *hold = NULL; + if (inc_tmp->path) + free(inc_tmp->path); + hold = (struct config_include_list*)inc_tmp; + inc_tmp = inc_tmp->next; + if (hold) + free(hold); + } + + if (conf->reference) + free(conf->reference); if (conf->path) free(conf->path); @@ -864,7 +905,7 @@ void config_file_initialize(struct config_file *conf) conf->entries = NULL; conf->tail = NULL; conf->last = NULL; - conf->references = NULL; + conf->reference = NULL; conf->includes = NULL; conf->include_depth = 0; conf->guaranteed_no_duplicates = false; @@ -1321,14 +1362,12 @@ bool config_file_write(config_file_t *conf, const char *path, bool sort) void config_file_dump(config_file_t *conf, FILE *file, bool sort) { struct config_entry_list *list = NULL; - struct path_linked_list *inc_tmp = conf->includes; - struct path_linked_list *ref_tmp = conf->references; + struct config_include_list *includes = conf->includes; - while (ref_tmp) + if (conf->reference) { - pathname_make_slashes_portable(ref_tmp->path); - fprintf(file, "#reference \"%s\"\n", ref_tmp->path); - ref_tmp = ref_tmp->next; + pathname_make_slashes_portable(conf->reference); + fprintf(file, "#reference \"%s\"\n", conf->reference); } if (sort) @@ -1353,10 +1392,10 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort) * '#include' directives must go *after* individual * config entries, otherwise they will override * any custom-set values */ - while (inc_tmp) + while (includes) { - fprintf(file, "#include \"%s\"\n", inc_tmp->path); - inc_tmp = inc_tmp->next; + fprintf(file, "#include \"%s\"\n", includes->path); + includes = includes->next; } } diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 36c20f1b09..320c5a2daa 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -70,76 +70,6 @@ #endif -/** - * Create a new linked list with one node in it - * The path on this node will be set to NULL -**/ -struct path_linked_list* path_linked_list_new() -{ - struct path_linked_list* paths_list = (struct path_linked_list*)malloc(sizeof(*paths_list)); - paths_list->next = NULL; - paths_list->path = NULL; - return paths_list; -} - -/* Free the entire linked list */ -bool path_linked_list_free(struct path_linked_list *in_path_linked_list) -{ - struct path_linked_list *node_tmp = NULL; - - node_tmp = (struct path_linked_list*)in_path_linked_list; - while (node_tmp) - { - struct path_linked_list *hold = NULL; - if (node_tmp->path) - free(node_tmp->path); - hold = (struct path_linked_list*)node_tmp; - node_tmp = node_tmp->next; - if (hold) - free(hold); - } - - return true; -} - -/** - * Add a node to the linked list with this path - * If the first node's path if it's not yet set the path - * on this node instead -**/ -void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, char *path) -{ - /* If the first item does not have a path this is - a list which has just been created, so we just fill - the path for the first item - */ - if (!in_path_linked_list->path) - { - in_path_linked_list->path = strdup(path); - } - else - { - struct path_linked_list *head = in_path_linked_list; - struct path_linked_list *node = (struct path_linked_list*) malloc(sizeof(*node)); - - if (node) - { - node->next = NULL; - node->path = strdup(path); - - if (head) - { - while (head->next) - head = head->next; - - head->next = node; - } - else - in_path_linked_list = node; - } - } -} - /** * path_get_archive_delim: * @path : path diff --git a/libretro-common/include/file/config_file.h b/libretro-common/include/file/config_file.h index 61ed615cc0..014d5ba722 100644 --- a/libretro-common/include/file/config_file.h +++ b/libretro-common/include/file/config_file.h @@ -54,12 +54,12 @@ RETRO_BEGIN_DECLS struct config_file { char *path; + char *reference; struct config_entry_list **entries_map; struct config_entry_list *entries; struct config_entry_list *tail; struct config_entry_list *last; - struct path_linked_list *includes; - struct path_linked_list *references; + struct config_include_list *includes; unsigned include_depth; bool guaranteed_no_duplicates; bool modified; @@ -92,8 +92,6 @@ config_file_t *config_file_new_alloc(void); void config_file_initialize(struct config_file *conf); -void config_file_add_reference(config_file_t *conf, char *path); - /* Loads a config file. Returns NULL if file doesn't exist. * NULL path will create an empty config file. * Includes cb callbacks to run custom code during config file processing.*/ @@ -111,6 +109,8 @@ config_file_t *config_file_new_from_path_to_string(const char *path); /* Frees config file. */ void config_file_free(config_file_t *conf); +void config_file_set_reference_path(config_file_t *conf, char *path); + bool config_file_deinitialize(config_file_t *conf); /* Loads a new config, and appends its data to conf. diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index 4b54dc42d1..452763fed2 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -51,28 +51,6 @@ enum RARCH_FILE_UNSUPPORTED }; -struct path_linked_list -{ - char *path; - struct path_linked_list *next; -}; - -/** - * Create a new linked list with one item in it - * The path on this item will be set to NULL -**/ -struct path_linked_list* path_linked_list_new(); - -/* Free the entire linked list */ -bool path_linked_list_free(struct path_linked_list *in_path_linked_list); - -/** - * Add a node to the linked list with this path - * If the first node's path if it's not yet set, - * set this instead -**/ -void path_linked_list_add_path(struct path_linked_list *in_path_linked_list, char *path); - /** * path_is_compressed_file: * @path : path