diff --git a/frontend/menu/history.c b/frontend/menu/history.c index 28e41344dc..d454ff4c88 100644 --- a/frontend/menu/history.c +++ b/frontend/menu/history.c @@ -80,7 +80,10 @@ void rom_history_push(rom_history_t *hist, } if (hist->size == hist->cap) + { rom_history_free_entry(&hist->entries[hist->cap - 1]); + hist->size--; + } memmove(hist->entries + 1, hist->entries, (hist->cap - 1) * sizeof(struct rom_history_entry)); @@ -88,31 +91,24 @@ void rom_history_push(rom_history_t *hist, hist->entries[0].path = strdup(path); hist->entries[0].core_path = strdup(core_path); hist->entries[0].core_name = strdup(core_name); + hist->size++; } static void rom_history_write_file(rom_history_t *hist) { - char *buf = (char*)malloc(PATH_MAX * 3); - if (!buf) - return; - FILE *file = fopen(hist->conf_path, "w"); if (!file) - { - free(buf); return; - } for (size_t i = 0; i < hist->size; i++) { - snprintf(buf, PATH_MAX * 3, "%s;%s;%s\n", + fprintf(file, "%s;%s;%s\n", hist->entries[i].path, hist->entries[i].core_path, hist->entries[i].core_name); } fclose(file); - free(buf); } void rom_history_free(rom_history_t *hist) @@ -120,14 +116,14 @@ void rom_history_free(rom_history_t *hist) if (!hist) return; - for (size_t i = 0; i < hist->cap; i++) - rom_history_free_entry(&hist->entries[i]); - free(hist->entries); - if (hist->conf_path) rom_history_write_file(hist); free(hist->conf_path); + for (size_t i = 0; i < hist->cap; i++) + rom_history_free_entry(&hist->entries[i]); + free(hist->entries); + free(hist); } @@ -140,19 +136,18 @@ static bool rom_history_read_file(rom_history_t *hist, const char *path) { FILE *file = fopen(path, "r"); if (!file) - return false; + return true; - char *buf = (char*)malloc(PATH_MAX * 3); - if (!buf) - { - fclose(file); - return false; - } + char buf[PATH_MAX * 3]; for (hist->size = 0; - hist->size < hist->cap && fgets(buf, PATH_MAX * 3, file); + hist->size < hist->cap && fgets(buf, sizeof(buf), file); hist->size++) { + char *last = buf + strlen(buf) - 1; + if (*last == '\n') + *last = '\0'; + struct string_list *list = string_split(buf, ";"); if (!list) break; @@ -171,7 +166,6 @@ static bool rom_history_read_file(rom_history_t *hist, const char *path) } fclose(file); - free(buf); return true; } diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 0ff9689a2e..1463ab6851 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -225,9 +225,12 @@ rgui_handle_t *rgui_init(void) (float)custom->width / custom->height; } + // TODO: Should make history path configurable. + // Possibly size as well. char history_path[PATH_MAX]; fill_pathname_resolve_relative(history_path, g_extern.config_path, ".retroarch-history.txt", sizeof(history_path)); + RARCH_LOG("[RGUI]: Opening history: %s.\n", history_path); rgui->history = rom_history_init(history_path, 20); return rgui; @@ -405,6 +408,8 @@ static void render_text(rgui_handle_t *rgui) (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2) || menu_type == RGUI_SETTINGS) snprintf(title, sizeof(title), "SETTINGS %s", dir); + else if (menu_type == RGUI_SETTINGS_OPEN_HISTORY) + strlcpy(title, "LOAD HISTORY", sizeof(title)); else { const char *core_name = rgui->info.library_name; @@ -579,6 +584,7 @@ static void render_text(rgui_handle_t *rgui) break; } case RGUI_SETTINGS_OPEN_FILEBROWSER: + case RGUI_SETTINGS_OPEN_HISTORY: case RGUI_SETTINGS_CORE_OPTIONS: case RGUI_SETTINGS_VIDEO_OPTIONS: #ifdef HAVE_SHADER_MANAGER @@ -1107,6 +1113,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Core", RGUI_SETTINGS_CORE, 0); #endif rgui_list_push(rgui->selection_buf, "Core Options", RGUI_SETTINGS_CORE_OPTIONS, 0); + rgui_list_push(rgui->selection_buf, "Load Game (History)", RGUI_SETTINGS_OPEN_HISTORY, 0); rgui_list_push(rgui->selection_buf, "Load Game", RGUI_SETTINGS_OPEN_FILEBROWSER, 0); rgui_list_push(rgui->selection_buf, "Video Options", RGUI_SETTINGS_VIDEO_OPTIONS, 0); @@ -1817,6 +1824,12 @@ static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) rgui->selection_ptr = 0; rgui->need_refresh = true; } + else if (type == RGUI_SETTINGS_OPEN_HISTORY && action == RGUI_ACTION_OK) + { + rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_OPEN_HISTORY, rgui->selection_ptr); + rgui->selection_ptr = 0; + rgui->need_refresh = true; + } else if ((menu_type_is_settings(type) || type == RGUI_SETTINGS_CORE || type == RGUI_SETTINGS_DISK_APPEND) && action == RGUI_ACTION_OK) { rgui_list_push(rgui->menu_stack, label, type, rgui->selection_ptr); @@ -1865,7 +1878,8 @@ static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) #ifdef HAVE_SHADER_MANAGER menu_type_is_shader_browser(menu_type) || #endif - menu_type == RGUI_SETTINGS_CORE || menu_type == RGUI_SETTINGS_DISK_APPEND)) + menu_type == RGUI_SETTINGS_CORE || menu_type == RGUI_SETTINGS_DISK_APPEND || + menu_type == RGUI_SETTINGS_OPEN_HISTORY)) { rgui->need_refresh = false; if ((menu_type >= RGUI_SETTINGS_CONTROLLER_1 && menu_type <= RGUI_SETTINGS_CONTROLLER_4)) @@ -1883,6 +1897,29 @@ static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) return 0; } +static void history_parse(rgui_handle_t *rgui) +{ + size_t history_size = rom_history_size(rgui->history); + for (size_t i = 0; i < history_size; i++) + { + const char *path = NULL; + const char *core_path = NULL; + const char *core_name = NULL; + + rom_history_get_index(rgui->history, i, + &path, &core_path, &core_name); + + char path_short[PATH_MAX]; + fill_pathname(path_short, path_basename(path), "", sizeof(path_short)); + + char fill_buf[PATH_MAX]; + snprintf(fill_buf, sizeof(fill_buf), "%s (%s)", + path_short, core_name); + + rgui_list_push(rgui->selection_buf, fill_buf, RGUI_FILE_PLAIN, 0); + } +} + static bool directory_parse(rgui_handle_t *rgui, const char *directory, unsigned menu_type, void *ctx) { if (!*directory) @@ -2155,6 +2192,34 @@ int rgui_iterate(rgui_handle_t *rgui) ret = -1; } + else if (menu_type == RGUI_SETTINGS_OPEN_HISTORY) + { + const char *path = NULL; + const char *core_path = NULL; + const char *core_name = NULL; + + rom_history_get_index(rgui->history, + rgui->selection_ptr, &path, &core_path, &core_name); + + strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro)); + +#ifdef HAVE_DYNAMIC + libretro_free_system_info(&rgui->info); + libretro_get_system_info(g_settings.libretro, &rgui->info); +#endif + // Dunno what to do for Wii here ... + + strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); + + g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); + rom_history_push(rgui->history, + g_extern.fullpath, + g_settings.libretro, + rgui->info.library_name); + + rgui->need_refresh = true; + ret = -1; + } else { fill_pathname_join(g_extern.fullpath, dir, path, sizeof(g_extern.fullpath)); @@ -2167,10 +2232,18 @@ int rgui_iterate(rgui_handle_t *rgui) char str[PATH_MAX]; fill_pathname_base(tmp, g_extern.fullpath, sizeof(tmp)); - snprintf(str, sizeof(str), "INFO - Loading %s...", tmp); + snprintf(str, sizeof(str), "INFO - Loading %s ...", tmp); msg_queue_push(g_extern.msg_queue, str, 1, 1); } + if (rgui->history) + { + rom_history_push(rgui->history, + g_extern.fullpath, + g_settings.libretro, + rgui->info.library_name); + } + rgui->need_refresh = true; // in case of zip extract rgui->msg_force = true; ret = -1; @@ -2206,11 +2279,17 @@ int rgui_iterate(rgui_handle_t *rgui) #ifdef HAVE_SHADER_MANAGER menu_type_is_shader_browser(menu_type) || #endif - menu_type == RGUI_SETTINGS_CORE || menu_type == RGUI_SETTINGS_DISK_APPEND)) + menu_type == RGUI_SETTINGS_CORE || + menu_type == RGUI_SETTINGS_OPEN_HISTORY || + menu_type == RGUI_SETTINGS_DISK_APPEND)) { rgui->need_refresh = false; rgui_list_clear(rgui->selection_buf); - directory_parse(rgui, dir, menu_type, rgui->selection_buf); + + if (menu_type == RGUI_SETTINGS_OPEN_HISTORY) + history_parse(rgui); + else + directory_parse(rgui, dir, menu_type, rgui->selection_buf); // Before a refresh, we could have deleted a file on disk, causing // selection_ptr to suddendly be out of range. Ensure it doesn't overflow. diff --git a/settings.c b/settings.c index 5721d33e2e..446a02238b 100644 --- a/settings.c +++ b/settings.c @@ -307,8 +307,8 @@ static config_file_t *open_default_config_file(void) config_file_t *conf = NULL; #if defined(_WIN32) && !defined(_XBOX) - // Just do something for now. char conf_path[PATH_MAX]; + // Just do something for now. strlcpy(conf_path, "retroarch.cfg", sizeof(conf_path)); conf = config_file_new(conf_path); if (!conf) @@ -320,6 +320,9 @@ static config_file_t *open_default_config_file(void) conf = config_file_new(conf_path); } } + + if (conf) + strlcpy(g_extern.config_path, conf_path, sizeof(g_extern.config_path)); #elif !defined(__CELLOS_LV2__) && !defined(_XBOX) char conf_path[PATH_MAX]; const char *xdg = getenv("XDG_CONFIG_HOME"); @@ -352,13 +355,10 @@ static config_file_t *open_default_config_file(void) conf = config_file_new(conf_path); RARCH_LOG("Looking for config in: \"/etc/retroarch.cfg\".\n"); } -#endif if (conf) - { - strlcpy(g_extern.config_path, conf_path, - sizeof(g_extern.config_path)); - } + strlcpy(g_extern.config_path, conf_path, sizeof(g_extern.config_path)); +#endif return conf; }