static int action_ok_directory_push(const char *path, const char *label, unsigned type, size_t idx) { menu_displaylist_info_t info = {0}; const char *menu_path = NULL; const char *menu_label = NULL; char cat_path[PATH_MAX_LENGTH]; menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return -1; if (!path) return -1; menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); info.list = menu->menu_list->menu_stack; info.type = type; info.directory_ptr = idx; strlcpy(info.path, cat_path, sizeof(info.path)); strlcpy(info.label, menu_label, sizeof(info.label)); return menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); }
static int action_ok_shader_preset_load(const char *path, const char *label, unsigned type, size_t idx) { const char *menu_path = NULL; char shader_path[PATH_MAX_LENGTH]; menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return -1; (void)shader_path; (void)menu_path; #ifdef HAVE_SHADER_MANAGER menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(shader_path, menu_path, path, sizeof(shader_path)); menu_shader_manager_set_preset(menu->shader, video_shader_parse_type(shader_path, RARCH_SHADER_NONE), shader_path); menu_list_flush_stack(menu->menu_list, "shader_options", 0); return 0; #else return -1; #endif }
static int action_ok_menu_wallpaper_load(const char *path, const char *label, unsigned type, size_t idx) { char wallpaper_path[PATH_MAX_LENGTH]; const char *menu_label = NULL; const char *menu_path = NULL; rarch_setting_t *setting = NULL; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; menu_list_get_last_stack(menu->menu_list, &menu_path, &menu_label, NULL); setting = menu_setting_find(menu_label); if (!setting) return -1; fill_pathname_join(wallpaper_path, menu_path, path, sizeof(wallpaper_path)); if (path_file_exists(wallpaper_path)) { strlcpy(settings->menu.wallpaper, wallpaper_path, sizeof(settings->menu.wallpaper)); rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE, wallpaper_path, "cb_menu_wallpaper", 0, 1, true); } menu_list_pop_stack_by_needle(menu->menu_list, setting->name); return 0; }
static int action_ok_cheat_file_load(const char *path, const char *label, unsigned type, size_t idx) { const char *menu_path = NULL; char cheat_path[PATH_MAX_LENGTH]; menu_handle_t *menu = menu_driver_get_ptr(); global_t *global = global_get_ptr(); if (!menu) return -1; (void)cheat_path; (void)menu_path; menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(cheat_path, menu_path, path, sizeof(cheat_path)); if (global->cheat) cheat_manager_free(global->cheat); global->cheat = cheat_manager_load(cheat_path); if (!global->cheat) return -1; menu_list_flush_stack(menu->menu_list, "core_cheat_options", 0); return 0; }
static int action_ok_database_manager_list(const char *path, const char *label, unsigned type, size_t idx) { char rdb_path[PATH_MAX_LENGTH]; menu_displaylist_info_t info = {0}; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; if (!path) return -1; if (!label) return -1; fill_pathname_join(rdb_path, settings->content_database, path, sizeof(rdb_path)); info.list = menu->menu_list->menu_stack; info.type = 0; info.directory_ptr = idx; strlcpy(info.path, rdb_path, sizeof(info.path)); strlcpy(info.label, "deferred_database_manager_list", sizeof(info.label)); return menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); }
static int deferred_push_cursor_manager_list_deferred(menu_displaylist_info_t *info) { char rdb_path[PATH_MAX_LENGTH]; int ret = -1; char *query = NULL; char *rdb = NULL; settings_t *settings = config_get_ptr(); config_file_t *conf = config_file_new(info->path); if (!conf || !settings) goto end; if (!config_get_string(conf, "query", &query)) goto end; if (!config_get_string(conf, "rdb", &rdb)) goto end; fill_pathname_join(rdb_path, settings->content_database, rdb, sizeof(rdb_path)); strlcpy(info->path_b, info->path, sizeof(info->path_b)); strlcpy(info->path, rdb_path, sizeof(info->path)); strlcpy(info->path_c, query, sizeof(info->path_c)); ret = deferred_push_dlist(info, DISPLAYLIST_DATABASE_QUERY); end: if (conf) config_file_free(conf); return ret; }
static int action_ok_shader_pass_load(const char *path, const char *label, unsigned type, size_t idx) { const char *menu_path = NULL; menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return -1; (void)menu_path; #ifdef HAVE_SHADER_MANAGER menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(menu->shader->pass[hack_shader_pass].source.path, menu_path, path, sizeof(menu->shader->pass[hack_shader_pass].source.path)); /* This will reset any changed parameters. */ video_shader_resolve_parameters(NULL, menu->shader); menu_list_flush_stack(menu->menu_list, "shader_options", 0); return 0; #else return -1; #endif }
static void nk_menu_context_reset(void *data) { char iconpath[PATH_MAX_LENGTH] = {0}; nk_menu_handle_t *nk = (nk_menu_handle_t*)data; settings_t *settings = config_get_ptr(); unsigned width = 0; unsigned height = 0; video_driver_get_size(&width, &height); if (!nk || !settings) return; fill_pathname_join(iconpath, settings->directory.assets, "nuklear", sizeof(iconpath)); fill_pathname_slash(iconpath, sizeof(iconpath)); nk_menu_layout(nk); nk_menu_init_device(nk); wimp_context_bg_destroy(nk); nk_menu_context_reset_textures(nk, iconpath); task_push_image_load(settings->path.menu_wallpaper, "cb_menu_wallpaper", menu_display_handle_wallpaper_upload, NULL); }
static void nk_menu_context_reset_textures(nk_menu_handle_t *nk, const char *iconpath) { unsigned i; for (i = 0; i < NK_TEXTURE_LAST; i++) { struct texture_image ti = {0}; char path[PATH_MAX_LENGTH] = {0}; switch(i) { case NK_TEXTURE_POINTER: fill_pathname_join(path, iconpath, "pointer.png", sizeof(path)); break; } if (string_is_empty(path) || !path_file_exists(path)) continue; image_texture_load(&ti, path); video_driver_texture_load(&ti, TEXTURE_FILTER_MIPMAP_LINEAR, &nk->textures.list[i]); image_texture_load(&ti, path); } }
void core_info_list_get_missing_firmware(core_info_list_t *core_info_list, const char *core, const char *systemdir, const core_info_firmware_t **firmware, size_t *num_firmware) { size_t i; char path[PATH_MAX_LENGTH] = {0}; core_info_t *info = NULL; if (!core_info_list || !core) return; *firmware = NULL; *num_firmware = 0; if (!(info = core_info_find(core_info_list, core))) return; *firmware = info->firmware; for (i = 1; i < info->firmware_count; i++) { fill_pathname_join(path, systemdir, info->firmware[i].path, sizeof(path)); info->firmware[i].missing = !path_file_exists(path); *num_firmware += info->firmware[i].missing; } qsort(info->firmware, info->firmware_count, sizeof(*info->firmware), core_info_firmware_cmp); }
static int action_ok_video_filter_file_load(const char *path, const char *label, unsigned type, size_t idx) { char filter_path[PATH_MAX_LENGTH]; const char *menu_path = NULL; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu) return -1; (void)filter_path; (void)menu_path; menu_list_get_last_stack(menu->menu_list, &menu_path, NULL, NULL); fill_pathname_join(filter_path, menu_path, path, sizeof(filter_path)); strlcpy(settings->video.softfilter_plugin, filter_path, sizeof(settings->video.softfilter_plugin)); event_command(EVENT_CMD_REINIT); menu_list_flush_stack(menu->menu_list, "video_options", 0); return 0; }
static int menu_archive_open(void) { char cat_path[PATH_MAX]; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; unsigned int type = 0; menu_list_pop_stack(driver.menu->menu_list); menu_list_get_last_stack(driver.menu->menu_list, &menu_path, &menu_label, NULL); if (menu_list_get_size(driver.menu->menu_list) == 0) return 0; menu_list_get_at_offset(driver.menu->menu_list->selection_buf, driver.menu->selection_ptr, &path, NULL, &type); fill_pathname_join(cat_path, menu_path, path, sizeof(cat_path)); menu_list_push_stack_refresh( driver.menu->menu_list, cat_path, menu_label, type, driver.menu->selection_ptr); return 0; }
static int file_archive_extract_cb(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t checksum, void *userdata) { const char *ext = path_get_extension(name); struct zip_extract_userdata *data = (struct zip_extract_userdata*)userdata; /* Extract first content that matches our list. */ if (ext && string_list_find_elem(data->ext, ext)) { char new_path[PATH_MAX_LENGTH] = {0}; if (data->extraction_directory) fill_pathname_join(new_path, data->extraction_directory, path_basename(name), sizeof(new_path)); else fill_pathname_resolve_relative(new_path, data->zip_path, path_basename(name), sizeof(new_path)); data->first_extracted_file_path = strdup(new_path); data->found_content = file_archive_perform_mode(new_path, valid_exts, cdata, cmode, csize, size, 0, NULL); return 0; } return 1; }
static void frontend_ps3_salamander_init(void) { CellPadData pad_data; cellPadInit(7); cellPadGetData(0, &pad_data); if(pad_data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] & CELL_PAD_CTRL_TRIANGLE) { //override path, boot first executable in cores directory RARCH_LOG("Fallback - Will boot first executable in RetroArch cores/ directory.\n"); find_and_set_first_file(); } else { //normal executable loading path char tmp_str[PATH_MAX]; bool config_file_exists = false; if (path_file_exists(config_path)) config_file_exists = true; //try to find CORE executable char core_executable[1024]; fill_pathname_join(core_executable, default_paths.core_dir, "CORE.SELF", sizeof(core_executable)); if(path_file_exists(core_executable)) { //Start CORE executable strlcpy(libretro_path, core_executable, sizeof(libretro_path)); RARCH_LOG("Start [%s].\n", libretro_path); } else { if (config_file_exists) { config_file_t * conf = config_file_new(config_path); config_get_array(conf, "libretro_path", tmp_str, sizeof(tmp_str)); config_file_free(conf); strlcpy(libretro_path, tmp_str, sizeof(libretro_path)); } if (!config_file_exists || !strcmp(libretro_path, "")) find_and_set_first_file(); else RARCH_LOG("Start [%s] found in retroarch.cfg.\n", libretro_path); if (!config_file_exists) { config_file_t *new_conf = config_file_new(NULL); config_set_string(new_conf, "libretro_path", libretro_path); config_file_write(new_conf, config_path); config_file_free(new_conf); } } } cellPadEnd(); }
void fill_pathname_join_concat(char *out_path, const char *dir, const char *path, const char *concat, size_t size) { fill_pathname_join(out_path, dir, path, size); strlcat(out_path, concat, size); }
bool fill_pathname_application_data(char *s, size_t len) { #if defined(_WIN32) && !defined(_XBOX) const char *appdata = getenv("APPDATA"); if (appdata) { strlcpy(s, appdata, len); return true; } #elif defined(OSX) const char *appdata = getenv("HOME"); if (appdata) { fill_pathname_join(s, appdata, "Library/Application Support/RetroArch", len); return true; } #elif !defined(RARCH_CONSOLE) const char *xdg = getenv("XDG_CONFIG_HOME"); const char *appdata = getenv("HOME"); /* XDG_CONFIG_HOME falls back to $HOME/.config. */ if (xdg) { fill_pathname_join(s, xdg, "retroarch", len); return true; } if (appdata) { #ifdef __HAIKU__ fill_pathname_join(s, appdata, "config/settings/retroarch/", len); #else fill_pathname_join(s, appdata, ".config/retroarch/", len); #endif return true; } #endif return false; }
void fill_pathname_join_special_ext(char *out_path, const char *dir, const char *path, const char *last, const char *ext, size_t size) { fill_pathname_join(out_path, dir, path, size); fill_string_join(out_path, last, size); strlcat(out_path, ext, size); }
const char *core_info_get_custom_config(const char *core_id, char *buffer, size_t buffer_length) { if (!core_id || !buffer || !buffer_length) return 0; fill_pathname_join(buffer, g_defaults.menu_config_dir, path_basename(core_id), buffer_length); fill_pathname(buffer, buffer, ".cfg", buffer_length); return buffer; }
void shader_manager_init(rgui_handle_t *rgui) { config_file_t *conf = NULL; char cgp_path[PATH_MAX]; const char *ext = path_get_extension(g_settings.video.shader_path); if (strcmp(ext, "glslp") == 0 || strcmp(ext, "cgp") == 0) { conf = config_file_new(g_settings.video.shader_path); if (conf) { if (gfx_shader_read_conf_cgp(conf, &rgui->shader)) gfx_shader_resolve_relative(&rgui->shader, g_settings.video.shader_path); config_file_free(conf); } } else if (strcmp(ext, "glsl") == 0 || strcmp(ext, "cg") == 0) { strlcpy(rgui->shader.pass[0].source.cg, g_settings.video.shader_path, sizeof(rgui->shader.pass[0].source.cg)); rgui->shader.passes = 1; } else { const char *shader_dir = *g_settings.video.shader_dir ? g_settings.video.shader_dir : g_settings.system_directory; fill_pathname_join(cgp_path, shader_dir, "rgui.glslp", sizeof(cgp_path)); conf = config_file_new(cgp_path); if (!conf) { fill_pathname_join(cgp_path, shader_dir, "rgui.cgp", sizeof(cgp_path)); conf = config_file_new(cgp_path); } if (conf) { if (gfx_shader_read_conf_cgp(conf, &rgui->shader)) gfx_shader_resolve_relative(&rgui->shader, cgp_path); config_file_free(conf); } } }
/** * cheat_manager_save: * @path : Path to cheats file (relative path). * * Saves cheats to file on disk. * * Returns: true (1) if successful, otherwise false (0). **/ bool cheat_manager_save(const char *path) { bool ret; unsigned i; config_file_t *conf = NULL; char buf[PATH_MAX_LENGTH] = {0}; char cheats_file[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); cheat_manager_t *handle = cheat_manager_state; fill_pathname_join(buf, settings->path.cheat_database, path, sizeof(buf)); fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file)); conf = config_file_new(cheats_file); if (!conf) conf = config_file_new(NULL); if (!conf) return false; if (!handle) { config_file_free(conf); return false; } config_set_int(conf, "cheats", handle->size); for (i = 0; i < handle->size; i++) { char key[64] = {0}; char desc_key[256] = {0}; char code_key[256] = {0}; char enable_key[256] = {0}; snprintf(key, sizeof(key), "cheat%u", i); snprintf(desc_key, sizeof(desc_key), "cheat%u_desc", i); snprintf(code_key, sizeof(code_key), "cheat%u_code", i); snprintf(enable_key, sizeof(enable_key), "cheat%u_enable", i); if (handle->cheats[i].desc) config_set_string(conf, desc_key, handle->cheats[i].desc); else config_set_string(conf, desc_key, handle->cheats[i].code); config_set_string(conf, code_key, handle->cheats[i].code); config_set_bool(conf, enable_key, handle->cheats[i].state); } ret = config_file_write(conf, cheats_file); config_file_free(conf); return ret; }
static bool input_autoconfigure_joypad_from_conf_dir( autoconfig_params_t *params) { size_t i; int ret = 0; int index = -1; int current_best = 0; config_file_t *conf = NULL; struct string_list *list = NULL; char path[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); fill_pathname_join(path,settings->input.autoconfig_dir, settings->input.joypad_driver, sizeof(path)); if (settings) list = dir_list_new(path, "cfg", false); if (!list || !list->size) list = dir_list_new(settings->input.autoconfig_dir, "cfg", false); if(!list) return false; RARCH_LOG("Autoconfig: %d profiles found\n", list->size); for (i = 0; i < list->size; i++) { conf = config_file_new(list->elems[i].data); ret = input_try_autoconfigure_joypad_from_conf(conf, params); if(ret >= current_best) { index = i; current_best = ret; } config_file_free(conf); } if(index >= 0 && current_best > 0) { RARCH_LOG("Autoconf: best configuration score=%d\n", current_best); conf = config_file_new(list->elems[index].data); input_autoconfigure_joypad_add(conf, params); config_file_free(conf); } else ret = 0; string_list_free(list); if (ret == 0) return false; return true; }
static int database_info_list_iterate_found_match( database_state_handle_t *db_state, database_info_handle_t *db, const char *zip_name ) { char db_crc[PATH_MAX_LENGTH] = {0}; char db_playlist_path[PATH_MAX_LENGTH] = {0}; char db_playlist_base_str[PATH_MAX_LENGTH] = {0}; char entry_path_str[PATH_MAX_LENGTH] = {0}; content_playlist_t *playlist = NULL; settings_t *settings = config_get_ptr(); const char *db_path = db_state->list->elems[db_state->list_index].data; const char *entry_path = db ? db->list->elems[db->list_ptr].data : NULL; database_info_t *db_info_entry = &db_state->info->list[db_state->entry_index]; fill_short_pathname_representation(db_playlist_base_str, db_path, sizeof(db_playlist_base_str)); path_remove_extension(db_playlist_base_str); strlcat(db_playlist_base_str, ".lpl", sizeof(db_playlist_base_str)); fill_pathname_join(db_playlist_path, settings->playlist_directory, db_playlist_base_str, sizeof(db_playlist_path)); playlist = content_playlist_init(db_playlist_path, 1000); snprintf(db_crc, sizeof(db_crc), "%08X|crc", db_info_entry->crc32); strlcpy(entry_path_str, entry_path, sizeof(entry_path_str)); if (zip_name && zip_name[0] != '\0') fill_pathname_join_delim(entry_path_str, entry_path_str, zip_name, '#', sizeof(entry_path_str)); #if 0 RARCH_LOG("Found match in database !\n"); RARCH_LOG("Path: %s\n", db_path); RARCH_LOG("CRC : %s\n", db_crc); RARCH_LOG("Playlist Path: %s\n", db_playlist_path); RARCH_LOG("Entry Path: %s\n", entry_path); RARCH_LOG("Playlist not NULL: %d\n", playlist != NULL); RARCH_LOG("ZIP entry: %s\n", zip_name); RARCH_LOG("entry path str: %s\n", entry_path_str); #endif content_playlist_push(playlist, entry_path_str, db_info_entry->name, "DETECT", "DETECT", db_crc, db_playlist_base_str); content_playlist_write_file(playlist); content_playlist_free(playlist); return 0; }
static void zarch_zui_font(void) { int font_size; char mediapath[PATH_MAX_LENGTH], fontpath[PATH_MAX_LENGTH]; menu_display_ctx_font_t font_info; settings_t *settings = config_get_ptr(); menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size); fill_pathname_join(mediapath, settings->assets_directory, "zarch", sizeof(mediapath)); fill_pathname_join(fontpath, mediapath, "Roboto-Condensed.ttf", sizeof(fontpath)); font_info.path = fontpath; font_info.size = font_size; if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info)) RARCH_WARN("Failed to load font."); }
/** * dir_list_new: * @dir : directory path. * @ext : allowed extensions of file directory entries to include. * @include_dirs : include directories as part of the finished directory listing? * @include_compressed : Only include files which match ext. Do not try to match compressed files, etc. * * Create a directory listing. * * Returns: pointer to a directory listing of type 'struct string_list *' on success, * NULL in case of error. Has to be freed manually. **/ struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs, bool include_compressed) { struct RDIR *entry = NULL; struct string_list *ext_list = NULL; struct string_list *list = NULL; if (!(list = string_list_new())) return NULL; if (ext) ext_list = string_split(ext, "|"); entry = retro_opendir(dir); if (!entry) goto error; if (retro_dirent_error(entry)) goto error; while (retro_readdir(entry)) { char file_path[PATH_MAX_LENGTH]; bool is_dir; int ret = 0; const char *name = retro_dirent_get_name(entry); const char *file_ext = path_get_extension(name); fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = retro_dirent_is_dir(entry, file_path); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, include_compressed, list, ext_list, file_ext); if (ret == -1) goto error; if (ret == 1) continue; } retro_closedir(entry); string_list_free(ext_list); return list; error: retro_closedir(entry); string_list_free(list); string_list_free(ext_list); return NULL; }
static int zip_extract_cb(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t checksum, void *userdata) { struct zip_extract_userdata *data = (struct zip_extract_userdata*)userdata; /* Extract first content that matches our list. */ const char *ext = path_get_extension(name); if (ext && string_list_find_elem(data->ext, ext)) { char new_path[PATH_MAX_LENGTH] = {0}; if (data->extraction_directory) fill_pathname_join(new_path, data->extraction_directory, path_basename(name), sizeof(new_path)); else fill_pathname_resolve_relative(new_path, data->zip_path, path_basename(name), sizeof(new_path)); switch (cmode) { case ZLIB_MODE_UNCOMPRESSED: data->found_content = zlib_write_file(new_path, cdata, size); return false; case ZLIB_MODE_DEFLATE: { int ret = 0; zlib_file_handle_t handle = {0}; if (!zlib_inflate_data_to_file_init(&handle, cdata, csize, size)) return 0; do{ ret = zlib_inflate_data_to_file_iterate(handle.stream); }while(ret == 0); if (zlib_inflate_data_to_file(&handle, ret, new_path, valid_exts, cdata, csize, size, checksum)) { strlcpy(data->zip_path, new_path, data->zip_path_size); data->found_content = true; return 0; } return 0; } default: return 0; } } return 1; }
static int zlib_extract_core_callback(const char *name, const char *valid_exts, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size, uint32_t crc32, void *userdata) { char path[PATH_MAX_LENGTH]; /* Make directory */ fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); path_basedir(path); if (!path_mkdir(path)) { RARCH_ERR("Failed to create directory: %s.\n", path); return 0; } /* Ignore directories. */ if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\') return 1; fill_pathname_join(path, (const char*)userdata, name, sizeof(path)); RARCH_LOG("path is: %s, CRC32: 0x%x\n", path, crc32); if (!zlib_perform_mode(path, valid_exts, cdata, cmode, csize, size, crc32, userdata)) { if (cmode == 0) { RARCH_ERR("Failed to write file: %s.\n", path); return 0; } goto error; } return 1; error: RARCH_ERR("Failed to deflate to: %s.\n", path); return 0; }
static int cb_update_shaders_glsl(void *data, size_t len) { char shaderdir[PATH_MAX_LENGTH]; settings_t *settings = config_get_ptr(); fill_pathname_join(shaderdir, settings->video.shader_dir, "shaders_glsl", sizeof(shaderdir)); if (!path_file_exists(shaderdir)) if (!path_mkdir(shaderdir)) return -1; return cb_generic_download(data, len, shaderdir); }
static int archive_load(void) { int ret = 0; menu_displaylist_info_t info = {0}; const char *menu_path = NULL; const char *menu_label = NULL; const char* path = NULL; size_t entry_idx = 0; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); size_t selected = menu_navigation_get_current_selection(); menu_handle_t *menu = menu_driver_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!menu || !menu_list) return -1; menu_list_pop_stack(menu_list); menu_list_get_last_stack(menu_list, &menu_path, &menu_label, NULL, NULL); if (menu_list_get_size(menu_list) == 0) return 0; menu_list_get_at_offset(menu_list->selection_buf, selected, &path, NULL, NULL, &entry_idx); ret = rarch_defer_core(global->core_info, menu_path, path, menu_label, menu->deferred_path, sizeof(menu->deferred_path)); fill_pathname_join(detect_content_path, menu_path, path, sizeof(detect_content_path)); switch (ret) { case -1: event_command(EVENT_CMD_LOAD_CORE); menu_common_load_content(false, CORE_TYPE_PLAIN); break; case 0: info.list = menu_list->menu_stack; info.type = 0; info.directory_ptr = selected; strlcpy(info.path, settings->libretro_directory, sizeof(info.path)); strlcpy(info.label, menu_hash_to_str(MENU_LABEL_DEFERRED_CORE_LIST), sizeof(info.label)); ret = menu_displaylist_push_list(&info, DISPLAYLIST_GENERIC); break; } return ret; }
/** * menu_content_defer_core: * @core_info : Core info list handle. * @dir : Directory. Gets joined with @path. * @path : Path. Gets joined with @dir. * @menu_label : Label identifier of menu setting. * @s : Deferred core path. Will be filled in * by function. * @len : Size of @s. * * Gets deferred core. * * Returns: 0 if there are multiple deferred cores and a * selection needs to be made from a list, otherwise * returns -1 and fills in @s with path to core. **/ int menu_content_defer_core(void *data, const char *dir, const char *path, const char *menu_label, char *s, size_t len) { char new_core_path[PATH_MAX_LENGTH]; const core_info_t *info = NULL; size_t supported = 0; core_info_list_t *core_info = (core_info_list_t*)data; uint32_t menu_label_hash = menu_hash_calculate(menu_label); fill_pathname_join(s, dir, path, len); #ifdef HAVE_COMPRESSION if (path_is_compressed_file(dir)) { /* In case of a compressed archive, we have to join with a hash */ /* We are going to write at the position of dir: */ retro_assert(strlen(dir) < strlen(s)); s[strlen(dir)] = '#'; } #endif if (core_info) core_info_list_get_supported_cores(core_info, s, &info, &supported); /* We started the menu with 'Load Content', we are * going to use the current core to load this. */ if (menu_label_hash == MENU_LABEL_LOAD_CONTENT) { runloop_ctl(RUNLOOP_CTL_CURRENT_CORE_GET, (void*)&info); if (info) { RARCH_LOG("Use the current core (%s) to load this content...\n", info->path); supported = 1; } } /* There are multiple deferred cores and a * selection needs to be made from a list, return 0. */ if (supported != 1) return 0; if (info) strlcpy(new_core_path, info->path, sizeof(new_core_path)); runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, s); if (path_file_exists(new_core_path)) runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, new_core_path); return -1; }
/** * rarch_defer_core: * @core_info : Core info list handle. * @dir : Directory. Gets joined with @path. * @path : Path. Gets joined with @dir. * @menu_label : Label identifier of menu setting. * @s : Deferred core path. Will be filled in * by function. * @len : Size of @s. * * Gets deferred core. * * Returns: 0 if there are multiple deferred cores and a * selection needs to be made from a list, otherwise * returns -1 and fills in @s with path to core. **/ int rarch_defer_core(core_info_list_t *core_info, const char *dir, const char *path, const char *menu_label, char *s, size_t len) { char new_core_path[PATH_MAX_LENGTH] = {0}; const core_info_t *info = NULL; size_t supported = 0; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); uint32_t menu_label_hash = msg_hash_calculate(menu_label); fill_pathname_join(s, dir, path, len); #ifdef HAVE_COMPRESSION if (path_is_compressed_file(dir)) { /* In case of a compressed archive, we have to join with a hash */ /* We are going to write at the position of dir: */ rarch_assert(strlen(dir) < strlen(s)); s[strlen(dir)] = '#'; } #endif if (core_info) core_info_list_get_supported_cores(core_info, s, &info, &supported); if (menu_label_hash == MENU_LABEL_LOAD_CONTENT) { info = (const core_info_t*)&global->core_info.current; if (info) { strlcpy(new_core_path, info->path, sizeof(new_core_path)); supported = 1; } } else strlcpy(new_core_path, info->path, sizeof(new_core_path)); /* There are multiple deferred cores and a * selection needs to be made from a list, return 0. */ if (supported != 1) return 0; strlcpy(global->path.fullpath, s, sizeof(global->path.fullpath)); if (path_file_exists(new_core_path)) strlcpy(settings->libretro, new_core_path, sizeof(settings->libretro)); return -1; }