From 99990173ccafe76af54b334bea854da17eda765a Mon Sep 17 00:00:00 2001 From: Themaister Date: Thu, 2 May 2013 14:42:58 +0200 Subject: [PATCH] Can load without ROM in RGUI (HAVE_DYNAMIC). Not sure how this will work on RARCH_CONSOLE, but it'll probably be checked for in startup on core load somehow and either start in menu or args->no_rom. --- dynamic.c | 42 +++++++++++++++++++++++++++++++++---- dynamic.h | 2 +- frontend/menu/history.c | 42 ++++++++++++++++++++++++++++--------- frontend/menu/menu_common.c | 26 ++++++++++++++++------- frontend/menu/menu_common.h | 1 + frontend/menu/rgui.c | 29 +++++++++++++++++++------ general.h | 1 + retroarch.c | 19 ++++++++++------- 8 files changed, 126 insertions(+), 36 deletions(-) diff --git a/dynamic.c b/dynamic.c index 55ca6077ad..1180c878a2 100644 --- a/dynamic.c +++ b/dynamic.c @@ -103,7 +103,23 @@ static bool environment_cb(unsigned cmd, void *data); #define DYNAMIC_EXT "so" #endif -static dylib_t libretro_get_system_info_lib(const char *path, struct retro_system_info *info) +static bool *load_no_rom_hook; +static bool environ_cb_get_system_info(unsigned cmd, void *data) +{ + switch (cmd) + { + case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME: + *load_no_rom_hook = *(const bool*)data; + break; + + default: + return false; + } + + return true; +} + +static dylib_t libretro_get_system_info_lib(const char *path, struct retro_system_info *info, bool *load_no_rom) { dylib_t lib = dylib_load(path); if (!lib) @@ -119,13 +135,30 @@ static dylib_t libretro_get_system_info_lib(const char *path, struct retro_syste } proc(info); + + if (load_no_rom) + { + *load_no_rom = false; + void (*set_environ)(retro_environment_t) = + (void (*)(retro_environment_t))dylib_proc(lib, "retro_set_environment"); + + if (!set_environ) + return lib; + + load_no_rom_hook = load_no_rom; + + // load_no_rom gets set in this callback. + set_environ(environ_cb_get_system_info); + } + return lib; } -bool libretro_get_system_info(const char *path, struct retro_system_info *info) +bool libretro_get_system_info(const char *path, struct retro_system_info *info, + bool *load_no_rom) { struct retro_system_info dummy_info = {0}; - dylib_t lib = libretro_get_system_info_lib(path, &dummy_info); + dylib_t lib = libretro_get_system_info_lib(path, &dummy_info, load_no_rom); if (!lib) return false; @@ -171,7 +204,7 @@ static bool find_first_libretro(char *path, size_t size, RARCH_LOG("Checking library: \"%s\".\n", list->elems[i].data); struct retro_system_info info = {0}; - dylib_t lib = libretro_get_system_info_lib(list->elems[i].data, &info); + dylib_t lib = libretro_get_system_info_lib(list->elems[i].data, &info, NULL); if (!lib) continue; @@ -374,6 +407,7 @@ void uninit_libretro_sym(void) g_extern.system.pix_fmt = RETRO_PIXEL_FORMAT_0RGB1555; g_extern.system.no_game = false; g_extern.system.shutdown = false; + g_extern.system.key_event = NULL; } #ifdef NEED_DYNAMIC diff --git a/dynamic.h b/dynamic.h index ffe7992058..c1c3f413cf 100644 --- a/dynamic.h +++ b/dynamic.h @@ -48,7 +48,7 @@ function_t dylib_proc(dylib_t lib, const char *proc); #ifdef HAVE_DYNAMIC // Gets system info from an arbitrary lib. // The struct returned must be freed as strings are allocated dynamically. -bool libretro_get_system_info(const char *path, struct retro_system_info *info); +bool libretro_get_system_info(const char *path, struct retro_system_info *info, bool *load_no_rom); void libretro_free_system_info(struct retro_system_info *info); #endif diff --git a/frontend/menu/history.c b/frontend/menu/history.c index c0c5f27ee3..4a7cde5f3c 100644 --- a/frontend/menu/history.c +++ b/frontend/menu/history.c @@ -63,7 +63,10 @@ void rom_history_push(rom_history_t *hist, { for (size_t i = 0; i < hist->size; i++) { - if (!strcmp(hist->entries[i].path, path) && + bool equal_path = (!path && !hist->entries[i].path) || + (path && hist->entries[i].path && !strcmp(path, hist->entries[i].path)); + + if (equal_path && !strcmp(hist->entries[i].core_path, core_path) && !strcmp(hist->entries[i].core_name, core_name)) { @@ -88,7 +91,7 @@ void rom_history_push(rom_history_t *hist, memmove(hist->entries + 1, hist->entries, (hist->cap - 1) * sizeof(struct rom_history_entry)); - hist->entries[0].path = strdup(path); + hist->entries[0].path = path ? strdup(path) : NULL; hist->entries[0].core_path = strdup(core_path); hist->entries[0].core_name = strdup(core_name); hist->size++; @@ -102,10 +105,19 @@ static void rom_history_write_file(rom_history_t *hist) for (size_t i = 0; i < hist->size; i++) { - fprintf(file, "%s;%s;%s\n", - hist->entries[i].path, - hist->entries[i].core_path, - hist->entries[i].core_name); + 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); + } } fclose(file); @@ -152,16 +164,26 @@ static bool rom_history_read_file(rom_history_t *hist, const char *path) if (!list) break; - if (list->size != 3) + if (list->size < 2 || list->size > 3) { string_list_free(list); break; } struct rom_history_entry *entry = &hist->entries[hist->size]; - entry->path = strdup(list->elems[0].data); - entry->core_path = strdup(list->elems[1].data); - entry->core_name = strdup(list->elems[2].data); + + 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); + } + string_list_free(list); } diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 750830b34d..52fd91a16e 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -365,9 +365,10 @@ void rgui_list_get_last(const rgui_list_t *list, void load_menu_game_prepare(void) { - if (*g_extern.fullpath) + if (*g_extern.fullpath || rgui->load_no_rom) { - if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW)) + if (*g_extern.fullpath && + g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW)) { char tmp[PATH_MAX]; char str[PATH_MAX]; @@ -378,7 +379,8 @@ void load_menu_game_prepare(void) } if (rgui->history) - rom_history_push(rgui->history, g_extern.fullpath, + rom_history_push(rgui->history, + *g_extern.fullpath ? g_extern.fullpath : NULL, g_settings.libretro, rgui->info.library_name); } @@ -412,7 +414,17 @@ void load_menu_game_history(unsigned game_index) game_index, &path, &core_path, &core_name); strlcpy(g_settings.libretro, core_path, sizeof(g_settings.libretro)); - strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); + + if (path) + { + rgui->load_no_rom = false; + strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); + } + else + { + rgui->load_no_rom = true; + *g_extern.fullpath = '\0'; + } #if !defined( HAVE_DYNAMIC) && defined(RARCH_CONSOLE) g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); @@ -421,10 +433,9 @@ void load_menu_game_history(unsigned game_index) g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN_START_GAME); #elif defined(HAVE_DYNAMIC) libretro_free_system_info(&rgui->info); - libretro_get_system_info(g_settings.libretro, &rgui->info); + libretro_get_system_info(g_settings.libretro, &rgui->info, NULL); g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); #endif - } bool load_menu_game(void) @@ -440,6 +451,7 @@ bool load_menu_game(void) args.state_path = *g_extern.savestate_dir ? g_extern.savestate_dir : NULL; args.rom_path = *g_extern.fullpath ? g_extern.fullpath : NULL; args.libretro_path = g_settings.libretro; + args.no_rom = rgui->load_no_rom; if (rarch_main_init_wrap(&args) == 0) { @@ -480,7 +492,7 @@ void menu_init(void) else if (*g_settings.libretro) { fill_pathname_basedir(rgui->libretro_dir, g_settings.libretro, sizeof(rgui->libretro_dir)); - libretro_get_system_info(g_settings.libretro, &rgui->info); + libretro_get_system_info(g_settings.libretro, &rgui->info, NULL); } #else retro_get_system_info(&rgui->info); diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index cd176ffb5f..5b7f89aebd 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -232,6 +232,7 @@ typedef struct char libretro_dir[PATH_MAX]; #endif struct retro_system_info info; + bool load_no_rom; #ifdef HAVE_OSKUTIL unsigned osk_param; diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index bc8ed1aa97..2cfd411ea4 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -1927,12 +1927,18 @@ static void history_parse(rgui_handle_t *rgui) 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); + + if (path) + { + char path_short[PATH_MAX]; + fill_pathname(path_short, path_basename(path), "", sizeof(path_short)); + + snprintf(fill_buf, sizeof(fill_buf), "%s (%s)", + path_short, core_name); + } + else + strlcpy(fill_buf, core_name, sizeof(fill_buf)); rgui_list_push(rgui->selection_buf, fill_buf, RGUI_FILE_PLAIN, 0); } @@ -2178,7 +2184,18 @@ int rgui_iterate(rgui_handle_t *rgui) #if defined(HAVE_DYNAMIC) fill_pathname_join(g_settings.libretro, dir, path, sizeof(g_settings.libretro)); libretro_free_system_info(&rgui->info); - libretro_get_system_info(g_settings.libretro, &rgui->info); + libretro_get_system_info(g_settings.libretro, &rgui->info, + &rgui->load_no_rom); + + // No ROM needed for this core, load game immediately. + if (rgui->load_no_rom) + { + g_extern.lifecycle_mode_state |= (1ULL << MODE_LOAD_GAME); + *g_extern.fullpath = '\0'; + rgui->msg_force = true; + ret = -1; + } + // Core selection on non-console just updates directory listing. // Will take affect on new ROM load. #elif defined(GEKKO) diff --git a/general.h b/general.h index c75025063e..10ab695a1d 100644 --- a/general.h +++ b/general.h @@ -611,6 +611,7 @@ struct rarch_main_wrap const char *config_path; const char *libretro_path; bool verbose; + bool no_rom; }; enum diff --git a/retroarch.c b/retroarch.c index c3fc8e43f1..f9f72e51a5 100644 --- a/retroarch.c +++ b/retroarch.c @@ -3131,15 +3131,18 @@ int rarch_main_init_wrap(const struct rarch_main_wrap *args) argv[argc++] = strdup("retroarch"); - if (args->rom_path) + if (!args->no_rom) { - RARCH_LOG("Using ROM: %s.\n", args->rom_path); - argv[argc++] = strdup(args->rom_path); - } - else - { - RARCH_LOG("No ROM, starting dummy core.\n"); - argv[argc++] = strdup("--menu"); + if (args->rom_path) + { + RARCH_LOG("Using ROM: %s.\n", args->rom_path); + argv[argc++] = strdup(args->rom_path); + } + else + { + RARCH_LOG("No ROM, starting dummy core.\n"); + argv[argc++] = strdup("--menu"); + } } if (args->sram_path)