void set_paths_redirect(const char *path) { global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* per-core saves: append the library_name to the save location */ if(global->system.info.library_name && strcmp(global->system.info.library_name,"No Core") && settings->sort_savefiles_enable) { strlcpy(orig_savefile_dir,global->savefile_dir,sizeof(global->savefile_dir)); fill_pathname_dir(global->savefile_dir,global->savefile_dir,global->system.info.library_name,sizeof(global->savefile_dir)); // if path doesn't exist try to create it, if everything fails revert to the original path if(!path_is_directory(global->savefile_dir)) if(!path_mkdir(global->savefile_dir)) strlcpy(global->savefile_dir,orig_savefile_dir,sizeof(global->savefile_dir)); } /* per-core states: append the library_name to the save location */ if (global->system.info.library_name && strcmp(global->system.info.library_name,"No Core") && settings->sort_savestates_enable) { strlcpy(orig_savestate_dir,global->savestate_dir,sizeof(global->savestate_dir)); fill_pathname_dir(global->savestate_dir,global->savestate_dir,global->system.info.library_name,sizeof(global->savestate_dir)); // if path doesn't exist try to create it, if everything fails revert to the original path if(!path_is_directory(global->savestate_dir)) if(!path_mkdir(global->savestate_dir)) strlcpy(global->savestate_dir,orig_savestate_dir,sizeof(global->savestate_dir)); } if(path_is_directory(global->savefile_dir)) strlcpy(global->savefile_name,global->savefile_dir,sizeof(global->savefile_dir)); if(path_is_directory(global->savestate_dir)) strlcpy(global->savestate_name,global->savestate_dir,sizeof(global->savestate_dir)); if (path_is_directory(global->savefile_name)) { fill_pathname_dir(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); RARCH_LOG("Redirecting save file to \"%s\".\n", global->savefile_name); } if (path_is_directory(global->savestate_name)) { fill_pathname_dir(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); RARCH_LOG("Redirecting save state to \"%s\".\n", global->savestate_name); } if (path_is_directory(global->cheatfile_name)) { fill_pathname_dir(global->cheatfile_name, global->basename, ".state", sizeof(global->cheatfile_name)); RARCH_LOG("Redirecting cheat file to \"%s\".\n", global->cheatfile_name); } }
static void set_basename(const char *path) { char *dst = NULL; global_t *global = global_get_ptr(); strlcpy(global->fullpath, path, sizeof(global->fullpath)); strlcpy(global->basename, path, sizeof(global->basename)); #ifdef HAVE_COMPRESSION /* Removing extension is a bit tricky for compressed files. * Basename means: * /file/to/path/game.extension should be: * /file/to/path/game * * Two things to consider here are: /file/to/path/ is expected * to be a directory and "game" is a single file. This is used for * states and srm default paths. * * For compressed files we have: * * /file/to/path/comp.7z#game.extension and * /file/to/path/comp.7z#folder/game.extension * * The choice I take here is: * /file/to/path/game as basename. We might end up in a writable * directory then and the name of srm and states are meaningful. * */ path_basedir(global->basename); fill_pathname_dir(global->basename, path, "", sizeof(global->basename)); #endif if ((dst = strrchr(global->basename, '.'))) *dst = '\0'; }
void path_set_basename(const char *path) { char *dst = NULL; path_set(RARCH_PATH_CONTENT, path); path_set(RARCH_PATH_BASENAME, path); #ifdef HAVE_COMPRESSION /* Removing extension is a bit tricky for compressed files. * Basename means: * /file/to/path/game.extension should be: * /file/to/path/game * * Two things to consider here are: /file/to/path/ is expected * to be a directory and "game" is a single file. This is used for * states and srm default paths. * * For compressed files we have: * * /file/to/path/comp.7z#game.extension and * /file/to/path/comp.7z#folder/game.extension * * The choice I take here is: * /file/to/path/game as basename. We might end up in a writable * directory then and the name of srm and states are meaningful. * */ path_basedir_wrapper(path_main_basename); fill_pathname_dir(path_main_basename, path, "", sizeof(path_main_basename)); #endif if ((dst = strrchr(path_main_basename, '.'))) *dst = '\0'; }
static void set_special_paths(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* First content file is the significant one. */ set_basename(argv[0]); global->subsystem_fullpaths = string_list_new(); rarch_assert(global->subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(global->subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (!global->has_set.state_path) fill_pathname_noext(global->name.savestate, global->name.base, ".state", sizeof(global->name.savestate)); if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, global->name.base, ".state", sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } /* If this is already set, * do not overwrite it as this was initialized before in * a menu or otherwise. */ if (settings->system_directory[0] == '\0') { RARCH_WARN("SYSTEM DIR is empty, assume CONTENT DIR %s\n",argv[0]); /*fill_pathname_basedir(settings->system_directory, argv[0], sizeof(settings->system_directory));*/ } }
static void config_load_core_specific(void) { *g_extern.core_specific_config_path = '\0'; if (!*g_settings.libretro #ifdef HAVE_DYNAMIC || g_extern.libretro_dummy #endif ) return; #ifdef HAVE_MENU if (*g_settings.rgui_config_directory) { path_resolve_realpath(g_settings.rgui_config_directory, sizeof(g_settings.rgui_config_directory)); strlcpy(g_extern.core_specific_config_path, g_settings.rgui_config_directory, sizeof(g_extern.core_specific_config_path)); } else #endif { // Use original config file's directory as a fallback. fill_pathname_basedir(g_extern.core_specific_config_path, g_extern.config_path, sizeof(g_extern.core_specific_config_path)); } fill_pathname_dir(g_extern.core_specific_config_path, g_settings.libretro, ".cfg", sizeof(g_extern.core_specific_config_path)); if (g_settings.core_specific_config) { char tmp[PATH_MAX]; strlcpy(tmp, g_settings.libretro, sizeof(tmp)); RARCH_LOG("Loading core-specific config from: %s.\n", g_extern.core_specific_config_path); if (!config_load_file(g_extern.core_specific_config_path, true)) RARCH_WARN("Core-specific config not found, reusing last config.\n"); // Force some parameters which are implied when using core specific configs. // Don't have the core config file overwrite the libretro path. strlcpy(g_settings.libretro, tmp, sizeof(g_settings.libretro)); // This must be true for core specific configs. g_settings.core_specific_config = true; } }
static void set_special_paths(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); /* First content file is the significant one. */ set_basename(argv[0]); global->subsystem_fullpaths = string_list_new(); rarch_assert(global->subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(global->subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (!global->has_set_state_path) fill_pathname_noext(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); if (path_is_directory(global->savestate_name)) { fill_pathname_dir(global->savestate_name, global->basename, ".state", sizeof(global->savestate_name)); RARCH_LOG("Redirecting save state to \"%s\".\n", global->savestate_name); } /* If this is already set, * do not overwrite it as this was initialized before in * a menu or otherwise. */ if (!*settings->system_directory) fill_pathname_basedir(settings->system_directory, argv[0], sizeof(settings->system_directory)); }
void path_set_special(char **argv, unsigned num_content) { unsigned i; union string_list_elem_attr attr; global_t *global = global_get_ptr(); /* First content file is the significant one. */ path_set_basename(argv[0]); subsystem_fullpaths = string_list_new(); retro_assert(subsystem_fullpaths); attr.i = 0; for (i = 0; i < num_content; i++) string_list_append(subsystem_fullpaths, argv[i], attr); /* We defer SRAM path updates until we can resolve it. * It is more complicated for special content types. */ if (global) { if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL)) fill_pathname_noext(global->name.savestate, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate)); if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } } }
static void rarch_init_savefile_paths(void) { global_t *global = global_get_ptr(); event_command(EVENT_CMD_SAVEFILES_DEINIT); global->savefiles = string_list_new(); rarch_assert(global->savefiles); if (*global->subsystem) { /* For subsystems, we know exactly which RAM types are supported. */ unsigned i, j; const struct retro_subsystem_info *info = libretro_find_subsystem_info( global->system.special, global->system.num_special, global->subsystem); /* We'll handle this error gracefully later. */ unsigned num_content = min(info ? info->num_roms : 0, global->subsystem_fullpaths ? global->subsystem_fullpaths->size : 0); bool use_sram_dir = path_is_directory(global->savefile_dir); for (i = 0; i < num_content; i++) { for (j = 0; j < info->roms[i].num_memory; j++) { union string_list_elem_attr attr; char path[PATH_MAX_LENGTH], ext[32]; const struct retro_subsystem_memory_info *mem = (const struct retro_subsystem_memory_info*) &info->roms[i].memory[j]; snprintf(ext, sizeof(ext), ".%s", mem->extension); if (use_sram_dir) { /* Redirect content fullpath to save directory. */ strlcpy(path, global->savefile_dir, sizeof(path)); fill_pathname_dir(path, global->subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } else { fill_pathname(path, global->subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } attr.i = mem->type; string_list_append(global->savefiles, path, attr); } } /* Let other relevant paths be inferred from the main SRAM location. */ if (!global->has_set_save_path) fill_pathname_noext(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); if (path_is_directory(global->savefile_name)) { fill_pathname_dir(global->savefile_name, global->basename, ".srm", sizeof(global->savefile_name)); RARCH_LOG("Redirecting save file to \"%s\".\n", global->savefile_name); } } else { char savefile_name_rtc[PATH_MAX_LENGTH]; union string_list_elem_attr attr; attr.i = RETRO_MEMORY_SAVE_RAM; string_list_append(global->savefiles, global->savefile_name, attr); /* Infer .rtc save path from save ram path. */ attr.i = RETRO_MEMORY_RTC; fill_pathname(savefile_name_rtc, global->savefile_name, ".rtc", sizeof(savefile_name_rtc)); string_list_append(global->savefiles, savefile_name_rtc, attr); } }
void set_paths_redirect(const char *path) { global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); rarch_system_info_t *info = rarch_system_info_get_ptr(); uint32_t global_library_name_hash = ((global && info->info.library_name && (info->info.library_name[0] != '\0')) ? msg_hash_calculate(info->info.library_name) : 0); if(global_library_name_hash != 0 && (global_library_name_hash != MENU_VALUE_NO_CORE)) { /* per-core saves: append the library_name to the save location */ if (settings->sort_savefiles_enable && global->dir.savefile[0] != '\0') { strlcpy(orig_savefile_dir,global->dir.savefile, sizeof(orig_savefile_dir)); fill_pathname_dir( global->dir.savefile, global->dir.savefile, info->info.library_name, sizeof(global->dir.savefile)); /* If path doesn't exist, try to create it, * if everything fails revert to the original path. */ if(!path_is_directory(global->dir.savefile) && global->dir.savefile[0] != '\0') { path_mkdir(global->dir.savefile); if(!path_is_directory(global->dir.savefile)) { RARCH_LOG("Reverting savefile directory to %s\n", orig_savefile_dir); strlcpy(global->dir.savefile, orig_savefile_dir, sizeof(global->dir.savefile)); } } } /* per-core states: append the library_name to the save location */ if (settings->sort_savestates_enable && global->dir.savestate[0] != '\0') { strlcpy(orig_savestate_dir, global->dir.savestate, sizeof(orig_savestate_dir)); fill_pathname_dir(global->dir.savestate, global->dir.savestate, info->info.library_name, sizeof(global->dir.savestate)); /* If path doesn't exist, try to create it. * If everything fails, revert to the original path. */ if(!path_is_directory(global->dir.savestate) && global->dir.savestate[0] != '\0') { path_mkdir(global->dir.savestate); if(!path_is_directory(global->dir.savestate)) { RARCH_LOG("Reverting savestate directory to %s\n", orig_savestate_dir); strlcpy(global->dir.savestate, orig_savestate_dir, sizeof(global->dir.savestate)); } } } } if(path_is_directory(global->dir.savefile)) strlcpy(global->name.savefile, global->dir.savefile, sizeof(global->name.savefile)); if(path_is_directory(global->dir.savestate)) strlcpy(global->name.savestate, global->dir.savestate, sizeof(global->name.savestate)); if (path_is_directory(global->name.savefile)) { fill_pathname_dir(global->name.savefile, global->name.base, ".srm", sizeof(global->name.savefile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO), global->name.savefile); } if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, global->name.base, ".state", sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } if (path_is_directory(global->name.cheatfile)) { fill_pathname_dir(global->name.cheatfile, global->name.base, ".state", sizeof(global->name.cheatfile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_CHEATFILE_TO), global->name.cheatfile); } }
void path_set_redirect(void) { char new_savefile_dir[PATH_MAX_LENGTH]; char new_savestate_dir[PATH_MAX_LENGTH]; uint32_t library_name_hash = 0; bool check_library_name_hash = false; rarch_system_info_t *info = NULL; global_t *global = global_get_ptr(); const char *old_savefile_dir = dir_get(RARCH_DIR_SAVEFILE); const char *old_savestate_dir = dir_get(RARCH_DIR_SAVESTATE); new_savefile_dir[0] = new_savestate_dir[0] = '\0'; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); if (info && info->info.library_name && !string_is_empty(info->info.library_name)) library_name_hash = msg_hash_calculate(info->info.library_name); /* Initialize current save directories * with the values from the config. */ strlcpy(new_savefile_dir, old_savefile_dir, sizeof(new_savefile_dir)); strlcpy(new_savestate_dir, old_savestate_dir, sizeof(new_savestate_dir)); check_library_name_hash = (library_name_hash != 0); #ifdef HAVE_MENU check_library_name_hash = check_library_name_hash && (library_name_hash != MENU_VALUE_NO_CORE); #endif if (check_library_name_hash) { settings_t *settings = config_get_ptr(); /* per-core saves: append the library_name to the save location */ if ( settings->sort_savefiles_enable && !string_is_empty(old_savefile_dir)) { fill_pathname_join( new_savefile_dir, old_savefile_dir, info->info.library_name, sizeof(new_savefile_dir)); /* If path doesn't exist, try to create it, * if everything fails revert to the original path. */ if(!path_is_directory(new_savefile_dir) && !string_is_empty(new_savefile_dir)) { path_mkdir(new_savefile_dir); if(!path_is_directory(new_savefile_dir)) { RARCH_LOG("%s %s\n", msg_hash_to_str(MSG_REVERTING_SAVEFILE_DIRECTORY_TO), old_savefile_dir); strlcpy(new_savefile_dir, old_savefile_dir, sizeof(new_savefile_dir)); } } } /* per-core states: append the library_name to the save location */ if (settings->sort_savestates_enable && !string_is_empty(old_savestate_dir)) { fill_pathname_join( new_savestate_dir, old_savestate_dir, info->info.library_name, sizeof(new_savestate_dir)); /* If path doesn't exist, try to create it. * If everything fails, revert to the original path. */ if(!path_is_directory(new_savestate_dir) && !string_is_empty(new_savestate_dir)) { path_mkdir(new_savestate_dir); if(!path_is_directory(new_savestate_dir)) { RARCH_LOG("%s %s\n", msg_hash_to_str(MSG_REVERTING_SAVESTATE_DIRECTORY_TO), old_savestate_dir); strlcpy(new_savestate_dir, old_savestate_dir, sizeof(new_savestate_dir)); } } } } /* Set savefile directory if empty based on content directory */ if (string_is_empty(new_savefile_dir)) { strlcpy(new_savefile_dir, path_main_basename, sizeof(new_savefile_dir)); path_basedir(new_savefile_dir); } if (global) { if(path_is_directory(new_savefile_dir)) strlcpy(global->name.savefile, new_savefile_dir, sizeof(global->name.savefile)); if(path_is_directory(new_savestate_dir)) strlcpy(global->name.savestate, new_savestate_dir, sizeof(global->name.savestate)); if (path_is_directory(global->name.savefile)) { fill_pathname_dir(global->name.savefile, path_main_basename, file_path_str(FILE_PATH_SRM_EXTENSION), sizeof(global->name.savefile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO), global->name.savefile); } if (path_is_directory(global->name.savestate)) { fill_pathname_dir(global->name.savestate, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.savestate)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVESTATE_TO), global->name.savestate); } if (path_is_directory(global->name.cheatfile)) { fill_pathname_dir(global->name.cheatfile, path_main_basename, file_path_str(FILE_PATH_STATE_EXTENSION), sizeof(global->name.cheatfile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_CHEATFILE_TO), global->name.cheatfile); } } dir_set(RARCH_DIR_CURRENT_SAVEFILE, new_savefile_dir); dir_set(RARCH_DIR_CURRENT_SAVESTATE, new_savestate_dir); }
static bool path_init_subsystem(void) { unsigned i, j; const struct retro_subsystem_info *info = NULL; rarch_system_info_t *system = NULL; global_t *global = global_get_ptr(); runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); if (!system) return false; if (path_is_empty(RARCH_PATH_SUBSYSTEM)) return false; /* For subsystems, we know exactly which RAM types are supported. */ info = libretro_find_subsystem_info( system->subsystem.data, system->subsystem.size, path_get(RARCH_PATH_SUBSYSTEM)); /* We'll handle this error gracefully later. */ if (info) { unsigned num_content = MIN(info->num_roms, path_is_empty(RARCH_PATH_SUBSYSTEM) ? 0 : subsystem_fullpaths->size); for (i = 0; i < num_content; i++) { for (j = 0; j < info->roms[i].num_memory; j++) { union string_list_elem_attr attr; char path[PATH_MAX_LENGTH]; char ext[32]; const struct retro_subsystem_memory_info *mem = (const struct retro_subsystem_memory_info*) &info->roms[i].memory[j]; path[0] = ext[0] = '\0'; snprintf(ext, sizeof(ext), ".%s", mem->extension); if (path_is_directory(dir_get(RARCH_DIR_SAVEFILE))) { /* Use SRAM dir */ /* Redirect content fullpath to save directory. */ strlcpy(path, dir_get(RARCH_DIR_SAVEFILE), sizeof(path)); fill_pathname_dir(path, subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } else { fill_pathname(path, subsystem_fullpaths->elems[i].data, ext, sizeof(path)); } attr.i = mem->type; string_list_append((struct string_list*)savefile_ptr_get(), path, attr); } } } if (global) { /* Let other relevant paths be inferred from the main SRAM location. */ if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL)) fill_pathname_noext(global->name.savefile, path_main_basename, file_path_str(FILE_PATH_SRM_EXTENSION), sizeof(global->name.savefile)); if (path_is_directory(global->name.savefile)) { fill_pathname_dir(global->name.savefile, path_main_basename, file_path_str(FILE_PATH_SRM_EXTENSION), sizeof(global->name.savefile)); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_REDIRECTING_SAVEFILE_TO), global->name.savefile); } } return true; }