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, COLLECTION_SIZE); 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); database_info_list_free(db_state->info); db_state->info = NULL; db_state->crc = 0; return 0; }
bool core_info_database_supports_content_path(const char *database_path, const char *path) { size_t i; char *database = NULL; if (!core_info_curr_list) return false; database = strdup(path_basename(database_path)); path_remove_extension(database); for (i = 0; i < core_info_curr_list->count; i++) { const core_info_t *info = &core_info_curr_list->list[i]; if (string_list_find_elem(info->supported_extensions_list, path_get_extension(path))) if (string_list_find_elem(info->databases_list, database)) { free(database); return true; } } free(database); return false; }
bool core_info_database_supports_content_path(const char *database_path, const char *path) { size_t i; char *database = NULL; const char *delim = NULL; const char *archive_path = NULL; if (!core_info_curr_list) return false; database = strdup(path_basename(database_path)); path_remove_extension(database); delim = path_get_archive_delim(path); if (delim) archive_path = delim - 1; /* if the path contains a compressed file and the core supports archives, * we don't want to look at this file */ if (archive_path) { for (i = 0; i < core_info_curr_list->count; i++) { const core_info_t *info = &core_info_curr_list->list[i]; if (!string_list_find_elem(info->databases_list, database)) continue; if ( !string_list_find_elem(info->supported_extensions_list, "zip") && !string_list_find_elem(info->supported_extensions_list, "7z")) continue; free(database); return false; } } for (i = 0; i < core_info_curr_list->count; i++) { const core_info_t *info = &core_info_curr_list->list[i]; if (!string_list_find_elem(info->supported_extensions_list, path_get_extension(path))) continue; if (!string_list_find_elem(info->databases_list, database)) continue; free(database); return true; } free(database); return false; }
/** * Loads only the basic information from a scenario. * rct2: 0x006761D6 */ int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info) { SDL_RWops* rw; log_verbose("loading scenario details, %s", path); rw = SDL_RWFromFile(path, "rb"); if (rw != NULL) { // Read first chunk sawyercoding_read_chunk(rw, (uint8*)header); if (header->type == S6_TYPE_SCENARIO) { // Read second chunk sawyercoding_read_chunk(rw, (uint8*)info); SDL_RWclose(rw); RCT2_GLOBAL(0x009AA00C, uint8) = 0; // Get filename utf8 filename[MAX_PATH]; const char *temp_filename = path_get_filename(path); int len = strnlen(temp_filename, MAX_PATH); safe_strncpy(filename, temp_filename, MAX_PATH); if (len == MAX_PATH) { filename[MAX_PATH - 1] = '\0'; log_warning("truncated string %s", filename); } path_remove_extension(filename); rct_string_id localisedStringIds[3]; if (language_get_localised_scenario_strings(filename, localisedStringIds)) { if (localisedStringIds[0] != (rct_string_id)STR_NONE) { safe_strncpy(info->name, language_get_string(localisedStringIds[0]), 64); } if (localisedStringIds[2] != (rct_string_id)STR_NONE) { safe_strncpy(info->details, language_get_string(localisedStringIds[2]), 256); } } else { // Checks for a scenario string object (possibly for localisation) if ((info->entry.flags & 0xFF) != 255) { if (object_get_scenario_text(&info->entry)) { rct_stex_entry* stex_entry = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TEXT_TEMP_CHUNK, rct_stex_entry*); format_string(info->name, stex_entry->scenario_name, NULL); format_string(info->details, stex_entry->details, NULL); RCT2_GLOBAL(0x009AA00C, uint8) = stex_entry->var_06; object_free_scenario_text(); } } }
bool core_info_database_supports_content_path(const char *database_path, const char *path) { char *database = NULL; const char *new_path = path_basename(database_path); if (string_is_empty(new_path)) return false; database = strdup(new_path); if (string_is_empty(database)) goto error; path_remove_extension(database); if (core_info_curr_list) { size_t i; for (i = 0; i < core_info_curr_list->count; i++) { const core_info_t *info = &core_info_curr_list->list[i]; if (!string_list_find_elem(info->supported_extensions_list, path_get_extension(path))) continue; if (!string_list_find_elem(info->databases_list, database)) continue; free(database); return true; } } error: if (database) free(database); return false; }
core_info_list_t *core_info_list_new(const char *modules_path) { struct string_list *contents = dir_list_new(modules_path, EXT_EXECUTABLES, false); size_t all_ext_len, i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; if (!contents) return NULL; core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); if (!core_info) goto error; core_info_list->list = core_info; core_info_list->count = contents->size; for (i = 0; i < contents->size; i++) { char info_path_base[PATH_MAX], info_path[PATH_MAX]; core_info[i].path = strdup(contents->elems[i].data); if (!core_info[i].path) break; fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base)); path_remove_extension(info_path_base); #if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE) char *substr = strrchr(info_path_base, '_'); if (substr) *substr = '\0'; #endif strlcat(info_path_base, ".info", sizeof(info_path_base)); fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path, info_path_base, sizeof(info_path)); core_info[i].data = config_file_new(info_path); if (core_info[i].data) { config_get_string(core_info[i].data, "display_name", &core_info[i].display_name); if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) && core_info[i].supported_extensions) core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|"); if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) && core_info[i].authors) core_info[i].authors_list = string_split(core_info[i].authors, "|"); } if (!core_info[i].display_name) core_info[i].display_name = strdup(path_basename(core_info[i].path)); } all_ext_len = 0; for (i = 0; i < core_info_list->count; i++) { all_ext_len += core_info_list->list[i].supported_extensions ? (strlen(core_info_list->list[i].supported_extensions) + 2) : 0; } if (all_ext_len) { all_ext_len += strlen("|zip"); core_info_list->all_ext = (char*)calloc(1, all_ext_len); } if (core_info_list->all_ext) { for (i = 0; i < core_info_list->count; i++) { if (core_info_list->list[i].supported_extensions) { strlcat(core_info_list->all_ext, core_info_list->list[i].supported_extensions, all_ext_len); strlcat(core_info_list->all_ext, "|", all_ext_len); } } strlcat(core_info_list->all_ext, "|zip", all_ext_len); } dir_list_free(contents); return core_info_list; error: if (contents) dir_list_free(contents); core_info_list_free(core_info_list); return NULL; }
void menu_shader_manager_init(void *data) { char cgp_path[PATH_MAX]; struct gfx_shader *shader; config_file_t *conf = NULL; const char *config_path = NULL; menu_handle_t *menu = (menu_handle_t*)data; if (!menu) return; shader = (struct gfx_shader*)menu->shader; if (*g_extern.core_specific_config_path && g_settings.core_specific_config) config_path = g_extern.core_specific_config_path; else if (*g_extern.config_path) config_path = g_extern.config_path; /* In a multi-config setting, we can't have * conflicts on menu.cgp/menu.glslp. */ if (config_path) { fill_pathname_base(menu->default_glslp, config_path, sizeof(menu->default_glslp)); path_remove_extension(menu->default_glslp); strlcat(menu->default_glslp, ".glslp", sizeof(menu->default_glslp)); fill_pathname_base(menu->default_cgp, config_path, sizeof(menu->default_cgp)); path_remove_extension(menu->default_cgp); strlcat(menu->default_cgp, ".cgp", sizeof(menu->default_cgp)); } else { strlcpy(menu->default_glslp, "menu.glslp", sizeof(menu->default_glslp)); strlcpy(menu->default_cgp, "menu.cgp", sizeof(menu->default_cgp)); } 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, shader)) { gfx_shader_resolve_relative(shader, g_settings.video.shader_path); gfx_shader_resolve_parameters(conf, shader); } config_file_free(conf); } } else if (strcmp(ext, "glsl") == 0 || strcmp(ext, "cg") == 0) { strlcpy(shader->pass[0].source.path, g_settings.video.shader_path, sizeof(shader->pass[0].source.path)); 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, "menu.glslp", sizeof(cgp_path)); conf = config_file_new(cgp_path); if (!conf) { fill_pathname_join(cgp_path, shader_dir, "menu.cgp", sizeof(cgp_path)); conf = config_file_new(cgp_path); } if (conf) { if (gfx_shader_read_conf_cgp(conf, shader)) { gfx_shader_resolve_relative(shader, cgp_path); gfx_shader_resolve_parameters(conf, shader); } config_file_free(conf); } } }
/** * menu_shader_manager_init: * * Initializes shader manager. **/ void menu_shader_manager_init(menu_handle_t *menu) { #ifdef HAVE_SHADER_MANAGER uint32_t ext_hash; char preset_path[PATH_MAX_LENGTH]; const char *ext = NULL; struct video_shader *shader = NULL; config_file_t *conf = NULL; const char *config_path = NULL; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (!menu) return; shader = (struct video_shader*)menu->shader; if (*global->path.core_specific_config && settings->core_specific_config) config_path = global->path.core_specific_config; else if (*global->path.config) config_path = global->path.config; /* In a multi-config setting, we can't have * conflicts on menu.cgp/menu.glslp. */ if (config_path) { fill_pathname_base(menu->default_glslp, config_path, sizeof(menu->default_glslp)); path_remove_extension(menu->default_glslp); strlcat(menu->default_glslp, ".glslp", sizeof(menu->default_glslp)); fill_pathname_base(menu->default_cgp, config_path, sizeof(menu->default_cgp)); path_remove_extension(menu->default_cgp); strlcat(menu->default_cgp, ".cgp", sizeof(menu->default_cgp)); } else { strlcpy(menu->default_glslp, "menu.glslp", sizeof(menu->default_glslp)); strlcpy(menu->default_cgp, "menu.cgp", sizeof(menu->default_cgp)); } ext = path_get_extension(settings->video.shader_path); ext_hash = menu_hash_calculate(ext); switch (ext_hash) { case MENU_VALUE_GLSLP: case MENU_VALUE_CGP: conf = config_file_new(settings->video.shader_path); if (conf) { if (video_shader_read_conf_cgp(conf, shader)) { video_shader_resolve_relative(shader, settings->video.shader_path); video_shader_resolve_parameters(conf, shader); } config_file_free(conf); } break; case MENU_VALUE_GLSL: case MENU_VALUE_CG: strlcpy(shader->pass[0].source.path, settings->video.shader_path, sizeof(shader->pass[0].source.path)); shader->passes = 1; break; default: { const char *shader_dir = *settings->video.shader_dir ? settings->video.shader_dir : settings->system_directory; fill_pathname_join(preset_path, shader_dir, "menu.glslp", sizeof(preset_path)); conf = config_file_new(preset_path); if (!conf) { fill_pathname_join(preset_path, shader_dir, "menu.cgp", sizeof(preset_path)); conf = config_file_new(preset_path); } if (conf) { if (video_shader_read_conf_cgp(conf, shader)) { video_shader_resolve_relative(shader, preset_path); video_shader_resolve_parameters(conf, shader); } config_file_free(conf); } } break; } #endif }
core_info_list_t *core_info_list_new(const char *modules_path) { size_t i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; struct string_list *contents = (struct string_list*)dir_list_new(modules_path, EXT_EXECUTABLES, false); if (!contents) return NULL; core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); if (!core_info) goto error; core_info_list->list = core_info; core_info_list->count = contents->size; for (i = 0; i < contents->size; i++) { char info_path_base[PATH_MAX], info_path[PATH_MAX]; core_info[i].path = strdup(contents->elems[i].data); if (!core_info[i].path) break; fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base)); path_remove_extension(info_path_base); #if defined(RARCH_MOBILE) || defined(RARCH_CONSOLE) char *substr = strrchr(info_path_base, '_'); if (substr) *substr = '\0'; #endif strlcat(info_path_base, ".info", sizeof(info_path_base)); fill_pathname_join(info_path, (*g_settings.libretro_info_path) ? g_settings.libretro_info_path : modules_path, info_path_base, sizeof(info_path)); core_info[i].data = config_file_new(info_path); if (core_info[i].data) { unsigned count = 0; config_get_string(core_info[i].data, "display_name", &core_info[i].display_name); config_get_string(core_info[i].data, "systemname", &core_info[i].systemname); config_get_uint(core_info[i].data, "firmware_count", &count); core_info[i].firmware_count = count; if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) && core_info[i].supported_extensions) core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|"); if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) && core_info[i].authors) core_info[i].authors_list = string_split(core_info[i].authors, "|"); if (config_get_string(core_info[i].data, "permissions", &core_info[i].permissions) && core_info[i].permissions) core_info[i].permissions_list = string_split(core_info[i].permissions, "|"); if (config_get_string(core_info[i].data, "notes", &core_info[i].notes) && core_info[i].notes) core_info[i].note_list = string_split(core_info[i].notes, "|"); } if (!core_info[i].display_name) core_info[i].display_name = strdup(path_basename(core_info[i].path)); } core_info_list_resolve_all_extensions(core_info_list); core_info_list_resolve_all_firmware(core_info_list); dir_list_free(contents); return core_info_list; error: if (contents) dir_list_free(contents); core_info_list_free(core_info_list); return NULL; }
/* Initialise runtime log, loading current parameters * if log file exists. Returned object must be free()'d. * Returns NULL if content_path and/or core_path are invalid */ runtime_log_t *runtime_log_init(const char *content_path, const char *core_path, bool log_per_core) { settings_t *settings = config_get_ptr(); core_info_list_t *core_info = NULL; runtime_log_t *runtime_log = NULL; const char *core_path_basename = path_basename(core_path); char content_name[PATH_MAX_LENGTH]; char core_name[PATH_MAX_LENGTH]; char log_file_dir[PATH_MAX_LENGTH]; char log_file_path[PATH_MAX_LENGTH]; char tmp_buf[PATH_MAX_LENGTH]; unsigned i; content_name[0] = '\0'; core_name[0] = '\0'; log_file_dir[0] = '\0'; log_file_path[0] = '\0'; tmp_buf[0] = '\0'; /* Error checking */ if (!settings) return NULL; if (string_is_empty(settings->paths.directory_playlist)) { RARCH_ERR("Playlist directory is undefined - cannot save runtime logs.\n"); return NULL; } if (string_is_empty(content_path) || string_is_empty(core_path_basename)) return NULL; if (string_is_equal(core_path, "builtin") || string_is_equal(core_path, file_path_str(FILE_PATH_DETECT))) return NULL; /* Get core name * Note: An annoyance - this is required even when * we are performing aggregate (not per core) logging, * since content name is sometimes dependent upon core * (e.g. see TyrQuake below) */ core_info_get_list(&core_info); if (!core_info) return NULL; for (i = 0; i < core_info->count; i++) { if (string_is_equal(path_basename(core_info->list[i].path), core_path_basename)) { strlcpy(core_name, core_info->list[i].core_name, sizeof(core_name)); break; } } if (string_is_empty(core_name)) return NULL; /* Get runtime log directory */ fill_pathname_join( tmp_buf, settings->paths.directory_playlist, "logs", sizeof(tmp_buf)); if (log_per_core) { fill_pathname_join( log_file_dir, tmp_buf, core_name, sizeof(log_file_dir)); } else { strlcpy(log_file_dir, tmp_buf, sizeof(log_file_dir)); } if (string_is_empty(log_file_dir)) return NULL; /* Create directory, if required */ if (!path_is_directory(log_file_dir)) { path_mkdir(log_file_dir); if(!path_is_directory(log_file_dir)) { RARCH_ERR("Failed to create directory for runtime log: %s.\n", log_file_dir); return NULL; } } /* Get content name * Note: TyrQuake requires a specific hack, since all * content has the same name... */ if (string_is_equal(core_name, "TyrQuake")) { const char *last_slash = find_last_slash(content_path); if (last_slash) { size_t path_length = last_slash + 1 - content_path; if (path_length < PATH_MAX_LENGTH) { memset(tmp_buf, 0, sizeof(tmp_buf)); strlcpy(tmp_buf, content_path, path_length * sizeof(char)); strlcpy(content_name, path_basename(tmp_buf), sizeof(content_name)); } } } else { /* path_remove_extension() requires a char * (not const) * so have to use a temporary buffer... */ tmp_buf[0] = '\0'; strlcpy(tmp_buf, path_basename(content_path), sizeof(tmp_buf)); strlcpy(content_name, path_remove_extension(tmp_buf), sizeof(content_name)); } if (string_is_empty(content_name)) return NULL; /* Build final log file path */ fill_pathname_join(log_file_path, log_file_dir, content_name, sizeof(log_file_path)); strlcat(log_file_path, file_path_str(FILE_PATH_RUNTIME_EXTENSION), sizeof(log_file_path)); if (string_is_empty(log_file_path)) return NULL; /* Phew... If we get this far then all is well. * > Create 'runtime_log' object */ runtime_log = (runtime_log_t*)calloc(1, sizeof(*runtime_log)); if (!runtime_log) return NULL; /* > Populate default values */ runtime_log->runtime.hours = 0; runtime_log->runtime.minutes = 0; runtime_log->runtime.seconds = 0; runtime_log->last_played.year = 0; runtime_log->last_played.month = 0; runtime_log->last_played.day = 0; runtime_log->last_played.hour = 0; runtime_log->last_played.minute = 0; runtime_log->last_played.second = 0; strlcpy(runtime_log->path, log_file_path, sizeof(runtime_log->path)); /* Load existing log file, if it exists */ runtime_log_read_file(runtime_log); return runtime_log; }
/** * event_save_core_config: * * Saves a new (core) configuration to a file. Filename is based * on heuristics to avoid typing. * * Returns: true (1) on success, otherwise false (0). **/ static bool event_save_core_config(void) { char config_dir[PATH_MAX_LENGTH] = {0}; char config_name[PATH_MAX_LENGTH] = {0}; char config_path[PATH_MAX_LENGTH] = {0}; char msg[128] = {0}; bool ret = false; bool found_path = false; bool overrides_active = false; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); *config_dir = '\0'; if (*settings->menu_config_directory) strlcpy(config_dir, settings->menu_config_directory, sizeof(config_dir)); else if (*global->path.config) /* Fallback */ fill_pathname_basedir(config_dir, global->path.config, sizeof(config_dir)); else { runloop_msg_queue_push(msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET), 1, 180, true); RARCH_ERR("%s\n", msg_hash_to_str(MSG_CONFIG_DIRECTORY_NOT_SET)); return false; } /* Infer file name based on libretro core. */ if (*settings->libretro && path_file_exists(settings->libretro)) { unsigned i; /* In case of collision, find an alternative name. */ for (i = 0; i < 16; i++) { char tmp[64]; fill_pathname_base(config_name, settings->libretro, sizeof(config_name)); path_remove_extension(config_name); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); if (i) snprintf(tmp, sizeof(tmp), "-%u.cfg", i); else strlcpy(tmp, ".cfg", sizeof(tmp)); snprintf(config_path, sizeof(config_path), "%s%s", config_path, tmp); if (!path_file_exists(config_path)) { found_path = true; break; } } } /* Fallback to system time... */ if (!found_path) { RARCH_WARN("Cannot infer new config path. Use current time.\n"); fill_dated_filename(config_name, "cfg", sizeof(config_name)); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); } /* Overrides block config file saving, make it appear as overrides * weren't enabled for a manual save */ if (runloop_ctl(RUNLOOP_CTL_IS_OVERRIDES_ACTIVE, NULL)) { runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); overrides_active = true; } if ((ret = config_save_file(config_path))) { strlcpy(global->path.config, config_path, sizeof(global->path.config)); snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", config_path); RARCH_LOG("%s\n", msg); } else { snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", config_path); RARCH_ERR("%s\n", msg); } runloop_msg_queue_push(msg, 1, 180, true); if (overrides_active) runloop_ctl(RUNLOOP_CTL_SET_OVERRIDES_ACTIVE, NULL); else runloop_ctl(RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE, NULL); return ret; }
/* Sets current thumbnail content to the specified playlist entry. * Returns true if content is valid. * > Note: It is always best to use playlists when setting * thumbnail content, since there is no guarantee that the * corresponding menu entry label will contain a useful * identifier (it may be 'tainted', e.g. with the current * core name). 'Real' labels should be extracted from source */ bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx) { const char *content_path = NULL; const char *content_label = NULL; const char *core_name = NULL; const char *db_name = NULL; const struct playlist_entry *entry = NULL; if (!path_data) return false; /* When content is updated, must regenerate right/left * thumbnail paths */ path_data->right_path[0] = '\0'; path_data->left_path[0] = '\0'; /* 'Reset' path_data content strings */ path_data->content_path[0] = '\0'; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; path_data->content_img[0] = '\0'; if (!playlist) return false; if (idx >= playlist_get_size(playlist)) return false; /* Read playlist values */ playlist_get_index(playlist, idx, &entry); content_path = entry->path; content_label = entry->label; core_name = entry->core_name; db_name = entry->db_name; /* Content without a path is invalid by definition */ if (string_is_empty(content_path)) return false; /* Cache content path * (This is required for imageviewer, history and favourites content) */ strlcpy(path_data->content_path, content_path, sizeof(path_data->content_path)); /* Cache core name * (This is required for imageviewer content) */ if (!string_is_empty(core_name)) strlcpy(path_data->content_core_name, core_name, sizeof(path_data->content_core_name)); /* Get content label */ if (!string_is_empty(content_label)) strlcpy(path_data->content_label, content_label, sizeof(path_data->content_label)); else fill_short_pathname_representation(path_data->content_label, content_path, sizeof(path_data->content_label)); /* Determine content image name */ fill_content_img(path_data); /* Redundant error check... */ if (string_is_empty(path_data->content_img)) return false; /* Thumbnail image name is done -> now check if * per-content database name is defined */ if (!string_is_empty(db_name)) { /* Hack: There is only one MAME thumbnail repo, * so filter any input starting with 'MAME...' */ if (strncmp(db_name, "MAME", 4) == 0) strlcpy(path_data->content_db_name, "MAME", sizeof(path_data->content_db_name)); else { char *db_name_no_ext = NULL; char tmp_buf[PATH_MAX_LENGTH]; tmp_buf[0] = '\0'; /* Remove .lpl extension * > path_remove_extension() requires a char * (not const) * so have to use a temporary buffer... */ strlcpy(tmp_buf, db_name, sizeof(tmp_buf)); db_name_no_ext = path_remove_extension(tmp_buf); if (!string_is_empty(db_name_no_ext)) strlcpy(path_data->content_db_name, db_name_no_ext, sizeof(path_data->content_db_name)); else strlcpy(path_data->content_db_name, tmp_buf, sizeof(path_data->content_db_name)); } } return true; }
void fill_pathname_join_noext(char *out_path, const char *dir, const char *path, size_t size) { fill_pathname_join(out_path, dir, path, size); path_remove_extension(out_path); }
static void task_database_handler(retro_task_t *task) { const char *name = NULL; database_info_handle_t *dbinfo = NULL; database_state_handle_t *dbstate = NULL; db_handle_t *db = NULL; if (!task) goto task_finished; db = (db_handle_t*)task->state; if (!db) goto task_finished; if (!db->scan_started) { db->scan_started = true; if (!string_is_empty(db->fullpath)) { if (db->is_directory) db->handle = database_info_dir_init(db->fullpath, DATABASE_TYPE_ITERATE, task, db->show_hidden_files); else db->handle = database_info_file_init(db->fullpath, DATABASE_TYPE_ITERATE, task); } task_free_title(task); if (db->handle) db->handle->status = DATABASE_STATUS_ITERATE_BEGIN; } dbinfo = db->handle; dbstate = &db->state; if (!dbinfo || task_get_cancelled(task)) goto task_finished; switch (dbinfo->status) { case DATABASE_STATUS_ITERATE_BEGIN: if (dbstate && !dbstate->list) { if (!string_is_empty(db->content_database_path)) dbstate->list = dir_list_new( db->content_database_path, "rdb", false, db->show_hidden_files, false, false); /* If the scan path matches a database path exactly then * save time by only processing that database. */ if (dbstate->list && db->is_directory) { size_t i; char *dirname = NULL; if (!string_is_empty(db->fullpath)) dirname = find_last_slash(db->fullpath) + 1; if (!string_is_empty(dirname)) { for (i = 0; i < dbstate->list->size; i++) { const char *data = dbstate->list->elems[i].data; char *dbname = NULL; bool strmatch = false; char *dbpath = strdup(data); path_remove_extension(dbpath); dbname = find_last_slash(dbpath) + 1; strmatch = strcasecmp(dbname, dirname) == 0; free(dbpath); if (strmatch) { struct string_list *single_list = string_list_new(); string_list_append(single_list, data, dbstate->list->elems[i].attr); dir_list_free(dbstate->list); dbstate->list = single_list; break; } } } } } dbinfo->status = DATABASE_STATUS_ITERATE_START; break; case DATABASE_STATUS_ITERATE_START: name = database_info_get_current_element_name(dbinfo); task_database_cleanup_state(dbstate); dbstate->list_index = 0; dbstate->entry_index = 0; task_database_iterate_start(dbinfo, name); break; case DATABASE_STATUS_ITERATE: if (task_database_iterate(db, dbstate, dbinfo) == 0) { dbinfo->status = DATABASE_STATUS_ITERATE_NEXT; dbinfo->type = DATABASE_TYPE_ITERATE; } break; case DATABASE_STATUS_ITERATE_NEXT: if (task_database_iterate_next(dbinfo) == 0) { dbinfo->status = DATABASE_STATUS_ITERATE_START; dbinfo->type = DATABASE_TYPE_ITERATE; } else { const char *msg = NULL; if (db->is_directory) msg = msg_hash_to_str(MSG_SCANNING_OF_DIRECTORY_FINISHED); else msg = msg_hash_to_str(MSG_SCANNING_OF_FILE_FINISHED); #ifdef RARCH_INTERNAL runloop_msg_queue_push(msg, 0, 180, true); #else fprintf(stderr, "msg: %s\n", msg); #endif ui_companion_driver_notify_refresh(); goto task_finished; } break; default: case DATABASE_STATUS_FREE: case DATABASE_STATUS_NONE: goto task_finished; } return; task_finished: if (task) task_set_finished(task, true); if (dbstate) { if (dbstate->list) dir_list_free(dbstate->list); } if (db) { if (!string_is_empty(db->playlist_directory)) free(db->playlist_directory); if (!string_is_empty(db->content_database_path)) free(db->content_database_path); if (!string_is_empty(db->fullpath)) free(db->fullpath); if (db->state.buf) free(db->state.buf); if (db->handle) database_info_free(db->handle); free(db); } if (dbinfo) free(dbinfo); }
void fill_pathname_basedir_noext(char *out_dir, const char *in_path, size_t size) { fill_pathname_basedir(out_dir, in_path, size); path_remove_extension(out_dir); }
void fill_pathname_base_noext(char *out, const char *in_path, size_t size) { fill_pathname_base(out, in_path, size); path_remove_extension(out); }
// Save a new config to a file. Filename is based on heuristics to avoid typing. bool menu_save_new_config(void) { char config_dir[PATH_MAX]; *config_dir = '\0'; if (*g_settings.rgui_config_directory) strlcpy(config_dir, g_settings.rgui_config_directory, sizeof(config_dir)); else if (*g_extern.config_path) // Fallback fill_pathname_basedir(config_dir, g_extern.config_path, sizeof(config_dir)); else { const char *msg = "Config directory not set. Cannot save new config."; msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, msg, 1, 180); RARCH_ERR("%s\n", msg); return false; } bool found_path = false; char config_name[PATH_MAX]; char config_path[PATH_MAX]; if (*g_settings.libretro && path_file_exists(g_settings.libretro)) // Infer file name based on libretro core. { unsigned i; // In case of collision, find an alternative name. for (i = 0; i < 16; i++) { fill_pathname_base(config_name, g_settings.libretro, sizeof(config_name)); path_remove_extension(config_name); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); char tmp[64]; *tmp = '\0'; if (i) snprintf(tmp, sizeof(tmp), "-%u.cfg", i); else strlcpy(tmp, ".cfg", sizeof(tmp)); strlcat(config_path, tmp, sizeof(config_path)); if (!path_file_exists(config_path)) { found_path = true; break; } } } // Fallback to system time ... if (!found_path) { RARCH_WARN("Cannot infer new config path. Use current time.\n"); fill_dated_filename(config_name, "cfg", sizeof(config_name)); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); } char msg[512]; bool ret; if (config_save_file(config_path)) { strlcpy(g_extern.config_path, config_path, sizeof(g_extern.config_path)); snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", config_path); RARCH_LOG("%s\n", msg); ret = true; } else { snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", config_path); RARCH_ERR("%s\n", msg); ret = false; } msg_queue_clear(g_extern.msg_queue); msg_queue_push(g_extern.msg_queue, msg, 1, 180); return ret; }
/** * event_save_core_config: * * Saves a new (core) configuration to a file. Filename is based * on heuristics to avoid typing. * * Returns: true (1) on success, otherwise false (0). **/ static bool event_save_core_config(void) { char config_dir[PATH_MAX_LENGTH] = {0}; char config_name[PATH_MAX_LENGTH] = {0}; char config_path[PATH_MAX_LENGTH] = {0}; char msg[PATH_MAX_LENGTH] = {0}; bool ret = false; bool found_path = false; bool overrides_active = false; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); *config_dir = '\0'; if (*settings->menu_config_directory) strlcpy(config_dir, settings->menu_config_directory, sizeof(config_dir)); else if (*global->config_path) /* Fallback */ fill_pathname_basedir(config_dir, global->config_path, sizeof(config_dir)); else { const char *message = "Config directory not set. Cannot save new config."; rarch_main_msg_queue_push(message, 1, 180, true); RARCH_ERR("%s\n", message); return false; } /* Infer file name based on libretro core. */ if (*settings->libretro && path_file_exists(settings->libretro)) { unsigned i; /* In case of collision, find an alternative name. */ for (i = 0; i < 16; i++) { char tmp[64] = {0}; fill_pathname_base(config_name, settings->libretro, sizeof(config_name)); path_remove_extension(config_name); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); *tmp = '\0'; if (i) snprintf(tmp, sizeof(tmp), "-%u.cfg", i); else strlcpy(tmp, ".cfg", sizeof(tmp)); strlcat(config_path, tmp, sizeof(config_path)); if (!path_file_exists(config_path)) { found_path = true; break; } } } /* Fallback to system time... */ if (!found_path) { RARCH_WARN("Cannot infer new config path. Use current time.\n"); fill_dated_filename(config_name, "cfg", sizeof(config_name)); fill_pathname_join(config_path, config_dir, config_name, sizeof(config_path)); } /* Overrides block config file saving, make it appear as overrides weren't enabled for a manual save */ if (global->overrides_active) { global->overrides_active = false; overrides_active = true; } if ((ret = config_save_file(config_path))) { strlcpy(global->config_path, config_path, sizeof(global->config_path)); snprintf(msg, sizeof(msg), "Saved new config to \"%s\".", config_path); RARCH_LOG("%s\n", msg); } else { snprintf(msg, sizeof(msg), "Failed saving config to \"%s\".", config_path); RARCH_ERR("%s\n", msg); } rarch_main_msg_queue_push(msg, 1, 180, true); global->overrides_active = overrides_active; return ret; }
core_info_list_t *core_info_list_new(void) { size_t i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; settings_t *settings = config_get_ptr(); struct string_list *contents = dir_list_new_special(NULL, DIR_LIST_CORES); if (!contents) return NULL; core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); if (!core_info) goto error; core_info_list->list = core_info; core_info_list->count = contents->size; for (i = 0; i < contents->size; i++) { char info_path_base[PATH_MAX_LENGTH] = {0}; char info_path[PATH_MAX_LENGTH] = {0}; core_info[i].path = strdup(contents->elems[i].data); if (!core_info[i].path) break; fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base)); path_remove_extension(info_path_base); #if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP)) char *substr = strrchr(info_path_base, '_'); if (substr) *substr = '\0'; #endif strlcat(info_path_base, ".info", sizeof(info_path_base)); fill_pathname_join(info_path, (*settings->libretro_info_path) ? settings->libretro_info_path : settings->libretro_directory, info_path_base, sizeof(info_path)); core_info[i].data = config_file_new(info_path); if (core_info[i].data) { unsigned count = 0; config_get_string(core_info[i].data, "display_name", &core_info[i].display_name); config_get_string(core_info[i].data, "corename", &core_info[i].core_name); config_get_string(core_info[i].data, "systemname", &core_info[i].systemname); config_get_string(core_info[i].data, "manufacturer", &core_info[i].system_manufacturer); config_get_uint(core_info[i].data, "firmware_count", &count); core_info[i].firmware_count = count; if (config_get_string(core_info[i].data, "supported_extensions", &core_info[i].supported_extensions) && core_info[i].supported_extensions) core_info[i].supported_extensions_list = string_split(core_info[i].supported_extensions, "|"); if (config_get_string(core_info[i].data, "authors", &core_info[i].authors) && core_info[i].authors) core_info[i].authors_list = string_split(core_info[i].authors, "|"); if (config_get_string(core_info[i].data, "permissions", &core_info[i].permissions) && core_info[i].permissions) core_info[i].permissions_list = string_split(core_info[i].permissions, "|"); if (config_get_string(core_info[i].data, "license", &core_info[i].licenses) && core_info[i].licenses) core_info[i].licenses_list = string_split(core_info[i].licenses, "|"); if (config_get_string(core_info[i].data, "categories", &core_info[i].categories) && core_info[i].categories) core_info[i].categories_list = string_split(core_info[i].categories, "|"); if (config_get_string(core_info[i].data, "database", &core_info[i].databases) && core_info[i].databases) core_info[i].databases_list = string_split(core_info[i].databases, "|"); if (config_get_string(core_info[i].data, "notes", &core_info[i].notes) && core_info[i].notes) core_info[i].note_list = string_split(core_info[i].notes, "|"); config_get_bool(core_info[i].data, "supports_no_game", &core_info[i].supports_no_game); } if (!core_info[i].display_name) core_info[i].display_name = strdup(path_basename(core_info[i].path)); } core_info_list_resolve_all_extensions(core_info_list); core_info_list_resolve_all_firmware(core_info_list); dir_list_free(contents); return core_info_list; error: if (contents) dir_list_free(contents); core_info_list_free(core_info_list); return NULL; }
void fill_short_pathname_representation_noext(char* out_rep, const char *in_path, size_t size) { fill_short_pathname_representation(out_rep, in_path, size); path_remove_extension(out_rep); }
/* Sets current thumbnail content to the specified image. * Returns true if content is valid */ bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name) { char *content_img_no_ext = NULL; if (!path_data) return false; /* When content is updated, must regenerate right/left * thumbnail paths */ path_data->right_path[0] = '\0'; path_data->left_path[0] = '\0'; /* 'Reset' path_data content strings */ path_data->content_path[0] = '\0'; path_data->content_label[0] = '\0'; path_data->content_core_name[0] = '\0'; path_data->content_db_name[0] = '\0'; path_data->content_img[0] = '\0'; if (string_is_empty(img_dir)) return false; if (string_is_empty(img_name)) return false; if (path_is_media_type(img_name) != RARCH_CONTENT_IMAGE) return false; /* Cache content image name */ strlcpy(path_data->content_img, img_name, sizeof(path_data->content_img)); /* Get image label */ content_img_no_ext = path_remove_extension(path_data->content_img); if (!string_is_empty(content_img_no_ext)) strlcpy(path_data->content_label, content_img_no_ext, sizeof(path_data->content_label)); else strlcpy(path_data->content_label, path_data->content_img, sizeof(path_data->content_label)); /* Set file path */ fill_pathname_join(path_data->content_path, img_dir, img_name, sizeof(path_data->content_path)); /* Set core name to "imageviewer" */ strlcpy(path_data->content_core_name, "imageviewer", sizeof(path_data->content_core_name)); /* Set database name (arbitrarily) to "_images_" * (required for compatibility with menu_thumbnail_update_path(), * but not actually used...) */ strlcpy(path_data->content_db_name, "_images_", sizeof(path_data->content_db_name)); /* Redundant error check */ if (string_is_empty(path_data->content_path)) return false; return true; }
void print_buf_lines(file_list_t *list, char *buf, const char *label, int buf_size, enum msg_file_type type, bool append, bool extended) { char c; int i, j = 0; char *line_start = buf; if (!buf || !buf_size) { menu_entries_append_enum(list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY), msg_hash_to_str(MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY), MENU_ENUM_LABEL_NO_ENTRIES_TO_DISPLAY, FILE_TYPE_NONE, 0, 0); return; } for (i = 0; i < buf_size; i++) { size_t ln; const char *core_date = NULL; const char *core_crc = NULL; const char *core_pathname = NULL; struct string_list *str_list = NULL; /* The end of the buffer, print the last bit */ if (*(buf + i) == '\0') break; if (*(buf + i) != '\n') continue; /* Found a line ending, print the line and compute new line_start */ /* Save the next char */ c = *(buf + i + 1); /* replace with \0 */ *(buf + i + 1) = '\0'; /* We need to strip the newline. */ ln = strlen(line_start) - 1; if (line_start[ln] == '\n') line_start[ln] = '\0'; str_list = string_split(line_start, " "); if (str_list->elems[0].data) core_date = str_list->elems[0].data; if (str_list->elems[1].data) core_crc = str_list->elems[1].data; if (str_list->elems[2].data) core_pathname = str_list->elems[2].data; (void)core_date; (void)core_crc; if (extended) { if (append) menu_entries_append_enum(list, core_pathname, "", MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); else menu_entries_prepend(list, core_pathname, "", MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); } else { if (append) menu_entries_append_enum(list, line_start, label, MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); else menu_entries_prepend(list, line_start, label, MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); } switch (type) { case FILE_TYPE_DOWNLOAD_CORE: { settings_t *settings = config_get_ptr(); if (settings) { char display_name[255]; char core_path[PATH_MAX_LENGTH]; char *last = NULL; display_name[0] = core_path[0] = '\0'; fill_pathname_join_noext( core_path, settings->paths.path_libretro_info, (extended && !string_is_empty(core_pathname)) ? core_pathname : line_start, sizeof(core_path)); path_remove_extension(core_path); last = (char*)strrchr(core_path, '_'); if (!string_is_empty(last)) { if (string_is_not_equal_fast(last, "_libretro", 9)) *last = '\0'; } strlcat(core_path, file_path_str(FILE_PATH_CORE_INFO_EXTENSION), sizeof(core_path)); if ( filestream_exists(core_path) && core_info_get_display_name( core_path, display_name, sizeof(display_name))) file_list_set_alt_at_offset(list, j, display_name); } } break; default: case FILE_TYPE_NONE: break; } j++; string_list_free(str_list); /* Restore the saved char */ *(buf + i + 1) = c; line_start = buf + i + 1; } if (append) file_list_sort_on_alt(list); /* If the buffer was completely full, and didn't end * with a newline, just ignore the partial last line. */ }
void core_info_get_name(const char *path, char *s, size_t len) { size_t i; core_info_t *core_info = NULL; core_info_list_t *core_info_list = NULL; settings_t *settings = config_get_ptr(); struct string_list *contents = dir_list_new_special(NULL, DIR_LIST_CORES); if (!contents) return; core_info_list = (core_info_list_t*)calloc(1, sizeof(*core_info_list)); if (!core_info_list) goto error; core_info = (core_info_t*)calloc(contents->size, sizeof(*core_info)); if (!core_info) goto error; core_info_list->list = core_info; core_info_list->count = contents->size; for (i = 0; i < contents->size; i++) { char info_path_base[PATH_MAX_LENGTH] = {0}; char info_path[PATH_MAX_LENGTH] = {0}; core_info[i].path = strdup(contents->elems[i].data); if (!core_info[i].path) break; if (strcmp(core_info[i].path, path) != 0) continue; fill_pathname_base(info_path_base, contents->elems[i].data, sizeof(info_path_base)); path_remove_extension(info_path_base); #if defined(RARCH_MOBILE) || (defined(RARCH_CONSOLE) && !defined(PSP)) char *substr = strrchr(info_path_base, '_'); if (substr) *substr = '\0'; #endif strlcat(info_path_base, ".info", sizeof(info_path_base)); fill_pathname_join(info_path, (*settings->libretro_info_path) ? settings->libretro_info_path : settings->libretro_directory, info_path_base, sizeof(info_path)); core_info[i].data = config_file_new(info_path); if (core_info[i].data) config_get_string(core_info[i].data, "corename", &core_info[i].core_name); strlcpy(s, core_info[i].core_name, len); } error: if (contents) dir_list_free(contents); contents = NULL; core_info_list_free(core_info_list); }