/** * event_command: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_command(enum event_command cmd) { unsigned i = 0; bool boolean = false; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); rarch_system_info_t *info = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); (void)i; switch (cmd) { case EVENT_CMD_MENU_REFRESH: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_REFRESH, NULL); #endif break; case EVENT_CMD_SET_PER_GAME_RESOLUTION: #if defined(GEKKO) { unsigned width = 0, height = 0; event_command(EVENT_CMD_VIDEO_SET_ASPECT_RATIO); if (video_driver_get_video_output_size(&width, &height)) { char msg[128] = {0}; video_driver_set_video_mode(width, height, true); snprintf(msg, sizeof(msg),"Resolution: %dx%d",width, height); runloop_msg_queue_push(msg, 1, 100, true); } } #endif break; case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CORE); #endif rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_ctl(RARCH_CTL_LOAD_CONTENT_FFMPEG, NULL); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_ctl(RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, NULL); break; case EVENT_CMD_LOAD_CONTENT: { #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CONTENT_PERSIST); #else char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)settings->libretro); rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)fullpath); event_command(EVENT_CMD_QUIT); #endif } break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_command(EVENT_CMD_LOAD_CORE_DEINIT); { #ifdef HAVE_MENU bool *ptr = NULL; struct retro_system_info *system = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system); if (menu_driver_ctl(RARCH_MENU_CTL_LOAD_NO_CONTENT_GET, &ptr)) event_update_system_info(system, ptr); #endif } break; case EVENT_CMD_LOAD_CORE: event_command(EVENT_CMD_LOAD_CORE_PERSIST); #ifndef HAVE_DYNAMIC event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: { unsigned idx = 0; unsigned *window_scale = NULL; runloop_ctl(RUNLOOP_CTL_GET_WINDOWED_SCALE, &window_scale); if (*window_scale == 0) return false; settings->video.scale = *window_scale; if (!settings->video.fullscreen) event_command(EVENT_CMD_REINIT); runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); } break; case EVENT_CMD_MENU_TOGGLE: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); else rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); #endif break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); runloop_msg_queue_push_new(MSG_RESET, 1, 120, true); #ifdef HAVE_CHEEVOS cheevos_set_cheats(); #endif core.retro_reset(); /* bSNES since v073r01 resets controllers to JOYPAD * after a reset, so just enforce it here. */ event_command(EVENT_CMD_CONTROLLERS_INIT); break; case EVENT_CMD_SAVE_STATE: if (settings->savestate_auto_index) settings->state_slot++; event_main_state(cmd); break; case EVENT_CMD_SAVE_STATE_DECREMENT: /* Slot -1 is (auto) slot. */ if (settings->state_slot >= 0) settings->state_slot--; break; case EVENT_CMD_SAVE_STATE_INCREMENT: settings->state_slot++; break; case EVENT_CMD_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_UNLOAD_CORE: runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL); event_command(EVENT_CMD_LOAD_CORE_DEINIT); break; case EVENT_CMD_QUIT: rarch_ctl(RARCH_CTL_QUIT, NULL); break; case EVENT_CMD_REINIT: { const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); if (hw_render->cache_context) video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT, NULL); else video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, NULL); event_command(EVENT_CMD_RESET_CONTEXT); video_driver_ctl(RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); /* Poll input to avoid possibly stale data to corrupt things. */ input_driver_ctl(RARCH_INPUT_CTL_POLL, NULL); #ifdef HAVE_MENU menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE); #endif } break; case EVENT_CMD_CHEATS_DEINIT: cheat_manager_state_free(); break; case EVENT_CMD_CHEATS_INIT: event_command(EVENT_CMD_CHEATS_DEINIT); event_init_cheats(); break; case EVENT_CMD_CHEATS_APPLY: cheat_manager_apply_cheats(); break; case EVENT_CMD_REMAPPING_DEINIT: break; case EVENT_CMD_REMAPPING_INIT: event_command(EVENT_CMD_REMAPPING_DEINIT); event_init_remapping(); break; case EVENT_CMD_REWIND_DEINIT: #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif state_manager_event_deinit(); break; case EVENT_CMD_REWIND_INIT: #ifdef HAVE_NETPLAY if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) #endif init_rewind(); break; case EVENT_CMD_REWIND_TOGGLE: if (settings->rewind_enable) event_command(EVENT_CMD_REWIND_INIT); else event_command(EVENT_CMD_REWIND_DEINIT); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS autosave_event_deinit(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_command(EVENT_CMD_AUTOSAVE_DEINIT); #ifdef HAVE_THREADS autosave_event_init(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!audio_driver_ctl(RARCH_AUDIO_CTL_STOP, NULL)) return false; break; case EVENT_CMD_AUDIO_START: if (audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!settings->audio.mute_enable && !audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL)) { RARCH_ERR("Failed to start audio driver. Will continue without audio.\n"); audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? msg_hash_to_str(MSG_AUDIO_MUTED): msg_hash_to_str(MSG_AUDIO_UNMUTED); if (!audio_driver_ctl(RARCH_AUDIO_CTL_MUTE_TOGGLE, NULL)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); return false; } runloop_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY input_overlay_free(); #endif break; case EVENT_CMD_OVERLAY_INIT: event_command(EVENT_CMD_OVERLAY_DEINIT); #ifdef HAVE_OVERLAY input_overlay_init(); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: audio_driver_dsp_filter_free(); break; case EVENT_CMD_DSP_FILTER_INIT: event_command(EVENT_CMD_DSP_FILTER_DEINIT); if (!*settings->audio.dsp_plugin) break; audio_driver_dsp_filter_init(settings->audio.dsp_plugin); break; case EVENT_CMD_GPU_RECORD_DEINIT: video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT, NULL); break; case EVENT_CMD_RECORD_DEINIT: if (!recording_deinit()) return false; break; case EVENT_CMD_RECORD_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!recording_init()) return false; break; case EVENT_CMD_HISTORY_DEINIT: if (g_defaults.history) { content_playlist_write_file(g_defaults.history); content_playlist_free(g_defaults.history); } g_defaults.history = NULL; break; case EVENT_CMD_HISTORY_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!settings->history_list_enable) return false; RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->content_history_path); g_defaults.history = content_playlist_init( settings->content_history_path, settings->content_history_size); break; case EVENT_CMD_CORE_INFO_DEINIT: runloop_ctl(RUNLOOP_CTL_CURRENT_CORE_LIST_FREE, NULL); break; case EVENT_CMD_CORE_INFO_INIT: event_command(EVENT_CMD_CORE_INFO_DEINIT); if (*settings->libretro_directory) runloop_ctl(RUNLOOP_CTL_CURRENT_CORE_LIST_INIT, NULL); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *cb = video_driver_callback(); event_deinit_core(true); if (cb) memset(cb, 0, sizeof(*cb)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core()) return false; break; case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: video_driver_ctl(RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES, NULL); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_ctl(RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, &boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_ctl(RARCH_DISPLAY_CTL_SET_ASPECT_RATIO, NULL); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblocking_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DRIVERS_DEINIT: { int flags = DRIVERS_CMD_ALL; driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); } break; case EVENT_CMD_DRIVERS_INIT: { int flags = DRIVERS_CMD_ALL; driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_AUDIO_REINIT: { int flags = DRIVER_AUDIO; driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_RESET_CONTEXT: event_command(EVENT_CMD_DRIVERS_DEINIT); event_command(EVENT_CMD_DRIVERS_INIT); break; case EVENT_CMD_QUIT_RETROARCH: rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); break; case EVENT_CMD_SHUTDOWN: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Shutting down...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -P now"); #endif break; case EVENT_CMD_RESUME: rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); break; case EVENT_CMD_RESTART_RETROARCH: { #if defined(GEKKO) && defined(HW_RVL) char new_path[PATH_MAX_LENGTH]; fill_pathname_join(new_path, g_defaults.dir.core, SALAMANDER_FILE, sizeof(new_path)); runloop_ctl(RUNLOOP_CTL_SET_CONTENT_PATH, new_path); #endif frontend_driver_set_fork(true, false); } break; case EVENT_CMD_MENU_SAVE_CURRENT_CONFIG: event_save_current_config(); break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; break; case EVENT_CMD_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif break; case EVENT_CMD_PAUSE_CHECKS: if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) { RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); event_command(EVENT_CMD_AUDIO_STOP); if (settings->video.black_frame_insertion) video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); } else { RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); event_command(EVENT_CMD_AUDIO_START); } break; case EVENT_CMD_PAUSE_TOGGLE: boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); boolean = !boolean; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_UNPAUSE: boolean = false; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_PAUSE: boolean = true; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_STOP); else event_command(EVENT_CMD_AUDIO_START); } else { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_START); } #endif break; case EVENT_CMD_SHADER_DIR_DEINIT: runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); break; case EVENT_CMD_SHADER_DIR_INIT: event_command(EVENT_CMD_SHADER_DIR_DEINIT); if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) return false; break; case EVENT_CMD_SAVEFILES: if (!global->savefiles || !global->sram.use) return false; for (i = 0; i < global->savefiles->size; i++) { unsigned type = global->savefiles->elems[i].attr.i; const char *path = global->savefiles->elems[i].data; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), type, msg_hash_to_str(MSG_TO), path); save_ram_file(path, type); } return true; case EVENT_CMD_SAVEFILES_DEINIT: if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; break; case EVENT_CMD_SAVEFILES_INIT: global->sram.use = global->sram.use && !global->sram.save_disable #ifdef HAVE_NETPLAY && (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL) || !global->netplay.is_client) #endif ; if (!global->sram.use) RARCH_LOG("%s\n", msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); if (global->sram.use) event_command(EVENT_CMD_AUTOSAVE_INIT); break; case EVENT_CMD_BSV_MOVIE_DEINIT: bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); break; case EVENT_CMD_BSV_MOVIE_INIT: event_command(EVENT_CMD_BSV_MOVIE_DEINIT); bsv_movie_ctl(BSV_MOVIE_CTL_INIT, NULL); break; case EVENT_CMD_NETPLAY_DEINIT: #ifdef HAVE_NETPLAY deinit_netplay(); #endif break; case EVENT_CMD_NETWORK_DEINIT: #ifdef HAVE_NETWORKING network_deinit(); #endif break; case EVENT_CMD_NETWORK_INIT: #ifdef HAVE_NETWORKING network_init(); #endif break; case EVENT_CMD_NETPLAY_INIT: event_command(EVENT_CMD_NETPLAY_DEINIT); #ifdef HAVE_NETPLAY if (!init_netplay()) return false; #endif break; case EVENT_CMD_NETPLAY_FLIP_PLAYERS: #ifdef HAVE_NETPLAY netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL); #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) return false; /* If we go fullscreen we drop all drivers and * reinitialize to be safe. */ settings->video.fullscreen = !settings->video.fullscreen; event_command(EVENT_CMD_REINIT); break; case EVENT_CMD_COMMAND_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_COMMAND_DEINIT, NULL); break; case EVENT_CMD_COMMAND_INIT: event_command(EVENT_CMD_COMMAND_DEINIT); input_driver_ctl(RARCH_INPUT_CTL_COMMAND_INIT, NULL); break; case EVENT_CMD_REMOTE_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_REMOTE_DEINIT, NULL); break; case EVENT_CMD_REMOTE_INIT: event_command(EVENT_CMD_REMOTE_DEINIT); input_driver_ctl(RARCH_INPUT_CTL_REMOTE_INIT, NULL); break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: content_temporary_free(); break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: if (!global) break; if (global->subsystem_fullpaths) string_list_free(global->subsystem_fullpaths); global->subsystem_fullpaths = NULL; break; case EVENT_CMD_LOG_FILE_DEINIT: retro_main_log_file_deinit(); break; case EVENT_CMD_DISK_EJECT_TOGGLE: if (info && info->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control; if (control) { bool new_state = !control->get_eject_state(); event_disk_control_set_eject(new_state, true); } } else runloop_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (info && info->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else runloop_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (info && info->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else runloop_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_RUMBLE_STOP: for (i = 0; i < MAX_USERS; i++) { input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } break; case EVENT_CMD_GRAB_MOUSE_TOGGLE: { static bool grab_mouse_state = false; bool grab_mouse_state_tmp; grab_mouse_state = !grab_mouse_state; if (!input_driver_grab_mouse(grab_mouse_state)) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); grab_mouse_state_tmp = !grab_mouse_state; video_driver_ctl(RARCH_DISPLAY_CTL_SHOW_MOUSE, &grab_mouse_state_tmp); } break; case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: rarch_perf_log(); break; case EVENT_CMD_VOLUME_UP: event_set_volume(0.5f); break; case EVENT_CMD_VOLUME_DOWN: event_set_volume(-0.5f); break; case EVENT_CMD_SET_FRAME_LIMIT: runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); break; case EVENT_CMD_NONE: default: return false; } return true; }
/** * content_file_load: * @special : subsystem of content to be loaded. Can be NULL. * content : * * Load content file (for libretro core). * * Returns : true if successful, otherwise false. **/ static bool content_file_load( struct retro_game_info *info, const struct string_list *content, content_information_ctx_t *content_ctx, char **error_string, const struct retro_subsystem_info *special ) { unsigned i; retro_ctx_load_content_info_t load_info; char msg[1024]; struct string_list *additional_path_allocs = string_list_new(); msg[0] = '\0'; if (!additional_path_allocs) return false; for (i = 0; i < content->size; i++) { int attr = content->elems[i].attr.i; const char *path = content->elems[i].data; bool need_fullpath = attr & 2; bool require_content = attr & 4; if (require_content && string_is_empty(path)) { snprintf(msg, sizeof(msg), "%s\n", msg_hash_to_str(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT)); *error_string = strdup(msg); goto error; } info[i].path = NULL; if (!string_is_empty(path)) info[i].path = path; if (!need_fullpath && !string_is_empty(path)) { /* Load the content into memory. */ ssize_t len = 0; if (!load_content_into_memory(i, path, (void**)&info[i].data, &len)) { snprintf(msg, sizeof(msg), "%s \"%s\".\n", msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), path); *error_string = strdup(msg); goto error; } info[i].size = len; } else { RARCH_LOG("%s\n", msg_hash_to_str( MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT)); #ifdef HAVE_COMPRESSION if ( !content_ctx->block_extract && need_fullpath && path_contains_compressed_file(path) && !load_content_from_compressed_archive( content_ctx, &info[i], i, additional_path_allocs, need_fullpath, path, error_string)) goto error; #endif } } load_info.content = content; load_info.special = special; load_info.info = info; if (!core_load_game(&load_info)) { snprintf(msg, sizeof(msg), "%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT)); *error_string = strdup(msg); goto error; } #ifdef HAVE_CHEEVOS if (!special) { const void *load_data = NULL; const char *path = content->elems[0].data; cheevos_set_cheats(); if (!string_is_empty(path)) load_data = info; cheevos_load(load_data); } #endif string_list_free(additional_path_allocs); return true; error: if (additional_path_allocs) string_list_free(additional_path_allocs); return false; }
/** * load_content: * @special : subsystem of content to be loaded. Can be NULL. * content : * * Load content file (for libretro core). * * Returns : true if successful, otherwise false. **/ static bool load_content( struct string_list *temporary_content, struct retro_game_info *info, const struct string_list *content, const struct retro_subsystem_info *special, struct string_list* additional_path_allocs ) { unsigned i; retro_ctx_load_content_info_t load_info; if (!info || !additional_path_allocs) return false; for (i = 0; i < content->size; i++) { int attr = content->elems[i].attr.i; bool need_fullpath = attr & 2; bool require_content = attr & 4; const char *path = content->elems[i].data; if (require_content && string_is_empty(path)) { RARCH_LOG("libretro core requires content, " "but nothing was provided.\n"); return false; } info[i].path = NULL; if (*path) info[i].path = path; if (!need_fullpath && !string_is_empty(path)) { if (!load_content_into_memory(&info[i], i, path)) return false; } else { RARCH_LOG("Content loading skipped. Implementation will" " load it on its own.\n"); #ifdef HAVE_COMPRESSION if (!load_content_from_compressed_archive( temporary_content, &info[i], i, additional_path_allocs, need_fullpath, path)) return false; #endif } } load_info.content = content; load_info.special = special; load_info.info = info; if (!core_load_game(&load_info)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT)); return false; } #ifdef HAVE_CHEEVOS if (!special) { const void *load_data = NULL; cheevos_set_cheats(); if (*content->elems[0].data) load_data = info; cheevos_load(load_data); } #endif return true; }