From bb3bac7e0deb442d9f545c71e39268697c004fdd Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 9 Jun 2013 21:59:48 +0200 Subject: [PATCH] Fix ROM history being deleted when ROM includes ;. Using ';' as a delimiter in history file was a mistake as it breaks when files have this file included. Instead, split on newline. To avoid reading broken history files, the history file path is changed. Also add game_history_path/size to config. --- config.def.h | 3 ++ frontend/menu/history.c | 66 ++++++++++++++----------------------- frontend/menu/menu_common.c | 14 +++++--- general.h | 2 ++ retroarch.cfg | 9 +++++ settings.c | 4 +++ 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/config.def.h b/config.def.h index d74a14b696..2df9370f1b 100644 --- a/config.def.h +++ b/config.def.h @@ -402,6 +402,9 @@ static const bool network_cmd_enable = false; static const uint16_t network_cmd_port = 55355; static const bool stdin_cmd_enable = false; +// Number of entries that will be kept in ROM history file. +static const unsigned game_history_size = 100; + //////////////////// // Keybinds, Joypad diff --git a/frontend/menu/history.c b/frontend/menu/history.c index 737eab4e35..080ec83365 100644 --- a/frontend/menu/history.c +++ b/frontend/menu/history.c @@ -106,19 +106,10 @@ static void rom_history_write_file(rom_history_t *hist) for (size_t i = 0; i < hist->size; i++) { - if (hist->entries[i].path) - { - fprintf(file, "%s;%s;%s\n", - hist->entries[i].path, - hist->entries[i].core_path, - hist->entries[i].core_name); - } - else - { - fprintf(file, "%s;%s\n", - hist->entries[i].core_path, - hist->entries[i].core_name); - } + fprintf(file, "%s\n%s\n%s\n", + hist->entries[i].path ? hist->entries[i].path : "", + hist->entries[i].core_path, + hist->entries[i].core_name); } fclose(file); @@ -151,43 +142,36 @@ static bool rom_history_read_file(rom_history_t *hist, const char *path) if (!file) return true; - char buf[PATH_MAX * 3]; + char buf[3][PATH_MAX]; + struct rom_history_entry *entry = NULL; + char *last = NULL; - for (hist->size = 0; - hist->size < hist->cap && fgets(buf, sizeof(buf), file); - hist->size++) + for (hist->size = 0; hist->size < hist->cap; hist->size++) { - char *last = buf + strlen(buf) - 1; - if (*last == '\n') - *last = '\0'; - - struct string_list *list = string_split(buf, ";"); - if (!list) - break; - - if (list->size < 2 || list->size > 3) + for (unsigned i = 0; i < 3; i++) { - string_list_free(list); - break; + *buf[i] = '\0'; + if (!fgets(buf[i], sizeof(buf[i]), file)) + goto end; + + last = strrchr(buf[i], '\n'); + if (last) + *last = '\0'; } - struct rom_history_entry *entry = &hist->entries[hist->size]; + entry = &hist->entries[hist->size]; - if (list->size == 3) - { - entry->path = strdup(list->elems[0].data); - entry->core_path = strdup(list->elems[1].data); - entry->core_name = strdup(list->elems[2].data); - } - else if (list->size == 2) - { - entry->core_path = strdup(list->elems[0].data); - entry->core_name = strdup(list->elems[1].data); - } + if (!*buf[1] || !*buf[2]) + goto end; - string_list_free(list); + + if (*buf[0]) + entry->path = strdup(buf[0]); + entry->core_path = strdup(buf[1]); + entry->core_name = strdup(buf[2]); } +end: fclose(file); return true; } diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index adc6c81b7d..cc7e7ddc5f 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -563,15 +563,19 @@ void menu_init(void) shader_manager_init(rgui); #endif - // TODO: Should make history path configurable. - // Possibly size as well. if (*g_extern.config_path) { char history_path[PATH_MAX]; - fill_pathname_resolve_relative(history_path, g_extern.config_path, - ".retroarch-history.txt", sizeof(history_path)); + if (*g_settings.game_history_path) + strlcpy(history_path, g_settings.game_history_path, sizeof(history_path)); + else + { + fill_pathname_resolve_relative(history_path, g_extern.config_path, + ".retroarch-game-history.txt", sizeof(history_path)); + } + RARCH_LOG("[RGUI]: Opening history: %s.\n", history_path); - rgui->history = rom_history_init(history_path, 100); + rgui->history = rom_history_init(history_path, g_settings.game_history_size); } } diff --git a/general.h b/general.h index 4a06fa76b7..66b4ba0da8 100644 --- a/general.h +++ b/general.h @@ -244,6 +244,8 @@ struct settings } input; char core_options_path[PATH_MAX]; + char game_history_path[PATH_MAX]; + unsigned game_history_size; char libretro[PATH_MAX]; char cheat_database[PATH_MAX]; diff --git a/retroarch.cfg b/retroarch.cfg index 2abd1adc2e..f25c051cff 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -25,8 +25,17 @@ # Path to core options config file. # This config file is used to expose core-specific options. # It will be written to by RetroArch. +# A default path will be assigned if not set. # core_options_path = +# Path to ROM load history file. +# RetroArch keeps track of all ROMs loaded in RGUI and from CLI directly for convenient quick loading. +# A default path will be assigned if not set. +# game_history_path = + +# Number of entries that will be kept in ROM history file. +# game_history_size = 100 + # Sets the "system" directory. # Implementations can query for this directory to load BIOSes, system-specific configs, etc. # system_directory = diff --git a/settings.c b/settings.c index f21ed60188..bf841401a4 100644 --- a/settings.c +++ b/settings.c @@ -217,6 +217,7 @@ void config_set_defaults(void) g_settings.network_cmd_enable = network_cmd_enable; g_settings.network_cmd_port = network_cmd_port; g_settings.stdin_cmd_enable = stdin_cmd_enable; + g_settings.game_history_size = game_history_size; rarch_assert(sizeof(g_settings.input.binds[0]) >= sizeof(retro_keybinds_1)); rarch_assert(sizeof(g_settings.input.binds[1]) >= sizeof(retro_keybinds_rest)); @@ -690,6 +691,9 @@ bool config_load_file(const char *path) CONFIG_GET_INT(network_cmd_port, "network_cmd_port"); CONFIG_GET_BOOL(stdin_cmd_enable, "stdin_cmd_enable"); + CONFIG_GET_PATH(game_history_path, "game_history_path"); + CONFIG_GET_INT(game_history_size, "game_history_size"); + CONFIG_GET_INT(input.turbo_period, "input_turbo_period"); CONFIG_GET_INT(input.turbo_duty_cycle, "input_duty_cycle");