static int action_ok_core_deferred_set(const char *path, const char *label, unsigned type, size_t idx) { char core_display_name[PATH_MAX_LENGTH]; menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return -1; if (menu->playlist) content_playlist_free(menu->playlist); menu->playlist = content_playlist_init(menu->db_playlist_file, 1000); core_info_get_name(path, core_display_name, sizeof(core_display_name)); idx = rdb_entry_start_game_selection_ptr; content_playlist_update(menu->playlist, idx, menu->playlist->entries[idx].path, menu->playlist->entries[idx].label, path , core_display_name, menu->playlist->entries[idx].crc32); content_playlist_free(menu->playlist); menu->playlist = NULL; menu_list_flush_stack(menu->menu_list, NULL, MENU_SETTINGS); return -1; }
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; }
/** * menu_free: * @menu : Menu handle. * * Frees a menu handle **/ void menu_free(menu_handle_t *menu) { global_t *global = global_get_ptr(); if (!menu) return; if (menu->playlist) content_playlist_free(menu->playlist); menu->playlist = NULL; menu_shader_free(menu); menu_input_free(); menu_navigation_free(); menu_driver_free(menu); #ifdef HAVE_DYNAMIC libretro_free_system_info(&g_system_menu); #endif menu_display_free(); menu_entries_free(); event_command(EVENT_CMD_HISTORY_DEINIT); if (global->core_info.list) core_info_list_free(global->core_info.list); if (global->core_info.current) free(global->core_info.current); global->core_info.current = NULL; free(menu); }
/** * menu_free: * @menu : Menu handle. * * Frees a menu handle **/ void menu_free(menu_handle_t *menu) { global_t *global = global_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); if (!menu || !disp) return; if (menu->playlist) content_playlist_free(menu->playlist); menu->playlist = NULL; menu_shader_free(menu); menu_driver_free(menu); #ifdef HAVE_DYNAMIC libretro_free_system_info(&global->menu.info); #endif menu_display_free(menu); menu_free_list(&menu->entries); event_command(EVENT_CMD_HISTORY_DEINIT); if (global->core_info) core_info_list_free(global->core_info); if (global->core_info_current) free(global->core_info_current); global->core_info_current = NULL; menu_driver_unset_alive(); free(menu); }
/** * content_playlist_init: * @path : Path to playlist contents file. * @size : Maximum capacity of playlist size. * * Creates and initializes a playlist. * * Returns: handle to new playlist if successful, otherwise NULL **/ content_playlist_t *content_playlist_init(const char *path, size_t size) { content_playlist_t *playlist = (content_playlist_t*) calloc(1, sizeof(*playlist)); if (!playlist) return NULL; playlist->entries = (content_playlist_entry_t*)calloc(size, sizeof(*playlist->entries)); if (!playlist->entries) goto error; playlist->cap = size; content_playlist_read_file(playlist, path); playlist->conf_path = strdup(path); return playlist; error: content_playlist_free(playlist); return NULL; }
/** * event_command: * @cmd : Event command index. * * Performs RetroArch 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; runloop_t *runloop = rarch_main_get_ptr(); driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); (void)i; switch (cmd) { case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CORE); #endif rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER); break; case EVENT_CMD_LOAD_CONTENT: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CONTENT_PERSIST); #else rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)settings->libretro); rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)global->fullpath); event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_DYNAMIC libretro_free_system_info(&global->menu.info); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_command(EVENT_CMD_LOAD_CORE_DEINIT); { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) event_update_system_info(&global->menu.info, &menu->load_no_content); #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 (global->bsv.movie) return false; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: if (global->pending.windowed_scale == 0) return false; settings->video.scale = global->pending.windowed_scale; if (!settings->video.fullscreen) event_command(EVENT_CMD_REINIT); global->pending.windowed_scale = 0; break; case EVENT_CMD_MENU_TOGGLE: if (menu_driver_alive()) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); else rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING); break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG(RETRO_LOG_RESETTING_CONTENT); rarch_main_msg_queue_push("Reset.", 1, 120, true); pretro_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_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_PREPARE_DUMMY: { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) menu->load_no_content = false; #endif rarch_main_data_deinit(); *global->fullpath = '\0'; rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); } break; case EVENT_CMD_UNLOAD_CORE: event_command(EVENT_CMD_PREPARE_DUMMY); event_command(EVENT_CMD_LOAD_CORE_DEINIT); break; case EVENT_CMD_QUIT: rarch_main_set_state(RARCH_ACTION_STATE_QUIT); break; case EVENT_CMD_REINIT: { const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); driver->video_cache_context = hw_render->cache_context; driver->video_cache_context_ack = false; event_command(EVENT_CMD_RESET_CONTEXT); driver->video_cache_context = false; /* Poll input to avoid possibly stale data to corrupt things. */ input_driver_poll(); #ifdef HAVE_MENU menu_display_fb_set_dirty(); if (menu_driver_alive()) event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE); #endif } break; case EVENT_CMD_CHEATS_DEINIT: if (!global) break; if (global->cheat) cheat_manager_free(global->cheat); global->cheat = NULL; break; case EVENT_CMD_CHEATS_INIT: event_command(EVENT_CMD_CHEATS_DEINIT); event_init_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: if (!global) break; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif if (global->rewind.state) state_manager_free(global->rewind.state); global->rewind.state = NULL; break; case EVENT_CMD_REWIND_INIT: 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 event_deinit_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_command(EVENT_CMD_AUTOSAVE_DEINIT); #ifdef HAVE_THREADS event_init_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!driver->audio_data) return false; if (!audio_driver_alive()) return false; if (!audio_driver_stop()) return false; break; case EVENT_CMD_AUDIO_START: if (!driver->audio_data || audio_driver_alive()) return false; if (!settings->audio.mute_enable && !audio_driver_start()) { RARCH_ERR("Failed to start audio driver. Will continue without audio.\n"); driver->audio_active = false; } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? "Audio muted." : "Audio unmuted."; if (!audio_driver_mute_toggle()) { RARCH_ERR("Failed to unmute audio.\n"); return false; } rarch_main_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY if (driver->overlay) input_overlay_free(driver->overlay); driver->overlay = NULL; memset(&driver->overlay_state, 0, sizeof(driver->overlay_state)); #endif break; case EVENT_CMD_OVERLAY_INIT: event_command(EVENT_CMD_OVERLAY_DEINIT); #ifdef HAVE_OVERLAY if (driver->osk_enable) { if (!*settings->osk.overlay) break; } else { if (!*settings->input.overlay) break; } driver->overlay = input_overlay_new(driver->osk_enable ? settings->osk.overlay : settings->input.overlay, driver->osk_enable ? settings->osk.enable : settings->input.overlay_enable, settings->input.overlay_opacity, settings->input.overlay_scale); if (!driver->overlay) RARCH_ERR("Failed to load overlay.\n"); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(driver->overlay, settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: if (!global) break; 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: if (!global) break; if (global->record.gpu_buffer) free(global->record.gpu_buffer); global->record.gpu_buffer = 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("Loading history file: [%s].\n", 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: if (!global) break; if (global->core_info) core_info_list_free(global->core_info); global->core_info = NULL; break; case EVENT_CMD_DATA_RUNLOOP_FREE: rarch_main_data_free(); break; case EVENT_CMD_CORE_INFO_INIT: event_command(EVENT_CMD_CORE_INFO_DEINIT); if (*settings->libretro_directory) global->core_info = core_info_list_new(); 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_apply_state_changes(); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_set_nonblock_state(boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_set_aspect_ratio(settings->video.aspect_ratio_idx); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblock_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(driver->overlay, settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(driver->overlay, settings->input.overlay_opacity); #endif break; case EVENT_CMD_DRIVERS_DEINIT: uninit_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_DRIVERS_INIT: init_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_AUDIO_REINIT: uninit_drivers(DRIVER_AUDIO); init_drivers(DRIVER_AUDIO); 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_main_set_state(RARCH_ACTION_STATE_FORCE_QUIT); break; case EVENT_CMD_RESUME: rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); break; case EVENT_CMD_RESTART_RETROARCH: #if defined(GEKKO) && defined(HW_RVL) fill_pathname_join(global->fullpath, g_defaults.core_dir, SALAMANDER_FILE, sizeof(global->fullpath)); #endif if (driver->frontend_ctx && driver->frontend_ctx->set_fork) driver->frontend_ctx->set_fork(true, false); 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->is_paused) { RARCH_LOG("Paused.\n"); event_command(EVENT_CMD_AUDIO_STOP); if (settings->video.black_frame_insertion) video_driver_cached_frame(); } else { RARCH_LOG("Unpaused.\n"); event_command(EVENT_CMD_AUDIO_START); } break; case EVENT_CMD_PAUSE_TOGGLE: runloop->is_paused = !runloop->is_paused; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_UNPAUSE: runloop->is_paused = false; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_PAUSE: runloop->is_paused = true; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: if (menu_driver_alive()) { 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); } break; case EVENT_CMD_SHADER_DIR_DEINIT: if (!global) break; dir_list_free(global->shader_dir.list); global->shader_dir.list = NULL; global->shader_dir.ptr = 0; break; case EVENT_CMD_SHADER_DIR_INIT: event_command(EVENT_CMD_SHADER_DIR_DEINIT); if (!*settings->video.shader_dir) return false; global->shader_dir.list = dir_list_new_special(NULL, DIR_LIST_SHADERS); if (!global->shader_dir.list || global->shader_dir.list->size == 0) { event_command(EVENT_CMD_SHADER_DIR_DEINIT); return false; } global->shader_dir.ptr = 0; dir_list_sort(global->shader_dir.list, false); for (i = 0; i < global->shader_dir.list->size; i++) RARCH_LOG("Found shader \"%s\"\n", global->shader_dir.list->elems[i].data); break; case EVENT_CMD_SAVEFILES: event_save_files(); break; 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->use_sram = global->use_sram && !global->sram_save_disable #ifdef HAVE_NETPLAY && (!driver->netplay_data || !global->netplay_is_client) #endif ; if (!global->use_sram) RARCH_LOG("SRAM will not be saved.\n"); if (global->use_sram) event_command(EVENT_CMD_AUTOSAVE_INIT); break; case EVENT_CMD_MSG_QUEUE_DEINIT: rarch_main_msg_queue_free(); break; case EVENT_CMD_MSG_QUEUE_INIT: event_command(EVENT_CMD_MSG_QUEUE_DEINIT); rarch_main_msg_queue_init(); rarch_main_data_init_queues(); break; case EVENT_CMD_BSV_MOVIE_DEINIT: if (!global) break; if (global->bsv.movie) bsv_movie_free(global->bsv.movie); global->bsv.movie = NULL; break; case EVENT_CMD_BSV_MOVIE_INIT: event_command(EVENT_CMD_BSV_MOVIE_DEINIT); event_init_movie(); 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_t *netplay = (netplay_t*)driver->netplay_data; if (!netplay) return false; netplay_flip_users(netplay); } #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_has_windowed()) 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: #ifdef HAVE_COMMAND if (driver->command) rarch_cmd_free(driver->command); driver->command = NULL; #endif break; case EVENT_CMD_COMMAND_INIT: event_command(EVENT_CMD_COMMAND_DEINIT); #ifdef HAVE_COMMAND event_init_command(); #endif break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: if (!global) break; if (global->temporary_content) event_free_temporary_content(); global->temporary_content = NULL; 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: if (!global) break; if (global->log_file && global->log_file != stderr) fclose(global->log_file); global->log_file = NULL; break; case EVENT_CMD_DISK_EJECT_TOGGLE: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (control) event_check_disk_eject(control); } else rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else rarch_main_msg_queue_push("Core does not support Disk Options.", 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else rarch_main_msg_queue_push("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; grab_mouse_state = !grab_mouse_state; if (!driver->input || !input_driver_grab_mouse(grab_mouse_state)) return false; RARCH_LOG("Grab mouse state: %s.\n", grab_mouse_state ? "yes" : "no"); video_driver_show_mouse(!grab_mouse_state); } 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_NONE: default: goto error; } return true; error: return false; }
static void menu_database_playlist_free(menu_handle_t *menu) { if (menu->db_playlist) content_playlist_free(menu->db_playlist); menu->db_playlist = NULL; }
/** * event_cmd_ctl: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_cmd_ctl(enum event_command cmd, void *data) { unsigned i = 0; bool boolean = false; 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_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); if (video_driver_get_video_output_size(&width, &height)) { char msg[128] = {0}; video_driver_set_video_mode(width, height, true); if (width == 0 || height == 0) strlcpy(msg, "Resolution: DEFAULT", sizeof(msg)); else 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_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); #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_cmd_ctl(EVENT_CMD_LOAD_CONTENT_PERSIST, NULL); #else char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, settings->libretro); event_cmd_ctl(EVENT_CMD_EXEC, (void*)fullpath); event_cmd_ctl(EVENT_CMD_QUIT, NULL); #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_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); { #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)) { core_info_ctx_find_t info_find; #if defined(HAVE_DYNAMIC) if (!(*settings->libretro)) return false; libretro_get_system_info(settings->libretro, system, ptr); #endif info_find.path = settings->libretro; if (!core_info_ctl(CORE_INFO_CTL_LOAD, &info_find)) return false; } #endif } break; case EVENT_CMD_LOAD_CORE: event_cmd_ctl(EVENT_CMD_LOAD_CORE_PERSIST, NULL); #ifndef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_QUIT, NULL); #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 #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) 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_cmd_ctl(EVENT_CMD_REINIT, NULL); 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(msg_hash_to_str(MSG_RESET), 1, 120, true); #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_SET_CHEATS, NULL); #endif core_ctl(CORE_CTL_RETRO_RESET, NULL); break; case EVENT_CMD_SAVE_STATE: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif 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_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); break; case EVENT_CMD_QUIT: rarch_ctl(RARCH_CTL_QUIT, NULL); break; case EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE: #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_TOGGLE_HARDCORE_MODE, NULL); #endif break; case EVENT_CMD_REINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); if (hwr->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_cmd_ctl(EVENT_CMD_RESET_CONTEXT, NULL); 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_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); #endif } break; case EVENT_CMD_CHEATS_DEINIT: cheat_manager_state_free(); break; case EVENT_CMD_CHEATS_INIT: event_cmd_ctl(EVENT_CMD_CHEATS_DEINIT, NULL); event_init_cheats(); break; case EVENT_CMD_CHEATS_APPLY: cheat_manager_apply_cheats(); break; case EVENT_CMD_REWIND_DEINIT: #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif state_manager_event_deinit(); break; case EVENT_CMD_REWIND_INIT: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif #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_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); else event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS autosave_event_deinit(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); #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_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); #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_cmd_ctl(EVENT_CMD_DSP_FILTER_DEINIT, NULL); 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_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); 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_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); 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: core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); break; case EVENT_CMD_CORE_INFO_INIT: event_cmd_ctl(EVENT_CMD_CORE_INFO_DEINIT, NULL); if (*settings->libretro_directory) core_info_ctl(CORE_INFO_CTL_LIST_INIT, NULL); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); event_deinit_core(true); if (hwr) memset(hwr, 0, sizeof(*hwr)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core(data)) 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_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: { /* RARCH_DRIVER_CTL_UNINIT clears the callback struct so we * need to make sure to keep a copy */ struct retro_hw_render_callback *hwr = NULL; struct retro_hw_render_callback hwr_copy; int flags = DRIVERS_CMD_ALL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); memcpy(&hwr_copy, hwr, sizeof(hwr_copy)); driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); memcpy(hwr, &hwr_copy, sizeof(*hwr)); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } 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_REBOOT: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Rebooting...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -r now"); #endif break; case EVENT_CMD_RESUME: rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); if (ui_companion_is_on_foreground()) ui_companion_driver_toggle(); break; case EVENT_CMD_RESTART_RETROARCH: if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) return 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_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); 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_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } break; case EVENT_CMD_PAUSE_TOGGLE: boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); boolean = !boolean; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_UNPAUSE: boolean = false; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_PAUSE: boolean = true; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); 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_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); else event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } else { if (settings->menu.pause_libretro) event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } #endif break; case EVENT_CMD_SHADER_DIR_DEINIT: runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); break; case EVENT_CMD_SHADER_DIR_INIT: event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) return false; break; case EVENT_CMD_SAVEFILES: { global_t *global = global_get_ptr(); if (!global->savefiles || !global->sram.use) return false; for (i = 0; i < global->savefiles->size; i++) { ram_type_t ram; ram.type = global->savefiles->elems[i].attr.i; ram.path = global->savefiles->elems[i].data; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), ram.type, msg_hash_to_str(MSG_TO), ram.path); content_ctl(CONTENT_CTL_SAVE_RAM_FILE, &ram); } } return true; case EVENT_CMD_SAVEFILES_DEINIT: { global_t *global = global_get_ptr(); if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; } break; case EVENT_CMD_SAVEFILES_INIT: { global_t *global = global_get_ptr(); global->sram.use = global->sram.use && !global->sram.save_disable; #ifdef HAVE_NETPLAY global->sram.use = global->sram.use && (!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_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); } break; case EVENT_CMD_BSV_MOVIE_DEINIT: bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); break; case EVENT_CMD_BSV_MOVIE_INIT: event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); 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_cmd_ctl(EVENT_CMD_NETPLAY_DEINIT, NULL); #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_cmd_ctl(EVENT_CMD_REINIT, NULL); break; case EVENT_CMD_COMMAND_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_COMMAND_DEINIT, NULL); break; case EVENT_CMD_COMMAND_INIT: event_cmd_ctl(EVENT_CMD_COMMAND_DEINIT, NULL); 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_cmd_ctl(EVENT_CMD_REMOTE_DEINIT, NULL); input_driver_ctl(RARCH_INPUT_CTL_REMOTE_INIT, NULL); break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: content_ctl(CONTENT_CTL_DEINIT, NULL); break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: { global_t *global = global_get_ptr(); 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_APPEND_IMAGE: { const char *path = (const char*)data; if (string_is_empty(path)) return false; return event_disk_control_append_image(path); } case EVENT_CMD_DISK_EJECT_TOGGLE: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (control) { bool new_state = !control->get_eject_state(); event_disk_control_set_eject(new_state, true); } } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else runloop_msg_queue_push( msg_hash_to_str(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: { bool ret = false; static bool grab_mouse_state = false; grab_mouse_state = !grab_mouse_state; if (grab_mouse_state) ret = input_driver_ctl(RARCH_INPUT_CTL_GRAB_MOUSE, NULL); else ret = input_driver_ctl(RARCH_INPUT_CTL_UNGRAB_MOUSE, NULL); if (!ret) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); if (grab_mouse_state) video_driver_ctl(RARCH_DISPLAY_CTL_HIDE_MOUSE, NULL); else video_driver_ctl(RARCH_DISPLAY_CTL_SHOW_MOUSE, NULL); } 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_EXEC: return event_cmd_exec(data); case EVENT_CMD_NONE: default: return false; } return true; }
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) { static struct retro_system_info menu_driver_system; static bool menu_driver_pending_quick_menu = false; static bool menu_driver_pending_action = false; static bool menu_driver_prevent_populate = false; static bool menu_driver_load_no_content = false; static bool menu_driver_alive = false; static bool menu_driver_data_own = false; static bool menu_driver_pending_quit = false; static bool menu_driver_pending_shutdown = false; static content_playlist_t *menu_driver_playlist = NULL; static struct video_shader *menu_driver_shader = NULL; static menu_handle_t *menu_driver_data = NULL; static const menu_ctx_driver_t *menu_driver_ctx = NULL; static void *menu_userdata = NULL; settings_t *settings = config_get_ptr(); switch (state) { case RARCH_MENU_CTL_IS_PENDING_ACTION: if (!menu_driver_pending_action) return false; menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_ACTION, NULL); break; case RARCH_MENU_CTL_SET_PENDING_ACTION: menu_driver_pending_action = true; break; case RARCH_MENU_CTL_UNSET_PENDING_ACTION: menu_driver_pending_action = false; break; case RARCH_MENU_CTL_DRIVER_DATA_GET: { menu_handle_t **driver_data = (menu_handle_t**)data; if (!driver_data) return false; *driver_data = menu_driver_data; } break; case RARCH_MENU_CTL_IS_PENDING_QUICK_MENU: return menu_driver_pending_quick_menu; case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU: menu_driver_pending_quick_menu = true; break; case RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU: menu_driver_pending_quick_menu = false; break; case RARCH_MENU_CTL_IS_PENDING_QUIT: return menu_driver_pending_quit; case RARCH_MENU_CTL_SET_PENDING_QUIT: menu_driver_pending_quit = true; break; case RARCH_MENU_CTL_UNSET_PENDING_QUIT: menu_driver_pending_quit = false; break; case RARCH_MENU_CTL_IS_PENDING_SHUTDOWN: return menu_driver_pending_shutdown; case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN: menu_driver_pending_shutdown = true; break; case RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN: menu_driver_pending_shutdown = false; break; case RARCH_MENU_CTL_DESTROY: menu_driver_pending_quick_menu = false; menu_driver_pending_action = false; menu_driver_pending_quit = false; menu_driver_pending_shutdown = false; menu_driver_prevent_populate = false; menu_driver_load_no_content = false; menu_driver_alive = false; menu_driver_data_own = false; menu_driver_ctx = NULL; menu_userdata = NULL; break; case RARCH_MENU_CTL_PLAYLIST_FREE: if (menu_driver_playlist) content_playlist_free(menu_driver_playlist); menu_driver_playlist = NULL; break; case RARCH_MENU_CTL_FIND_DRIVER: { int i; driver_ctx_info_t drv; settings_t *settings = config_get_ptr(); drv.label = "menu_driver"; drv.s = settings->menu.driver; driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); i = drv.len; if (i >= 0) menu_driver_ctx = (const menu_ctx_driver_t*) menu_driver_find_handle(i); else { unsigned d; RARCH_WARN("Couldn't find any menu driver named \"%s\"\n", settings->menu.driver); RARCH_LOG_OUTPUT("Available menu drivers are:\n"); for (d = 0; menu_driver_find_handle(d); d++) RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d)); RARCH_WARN("Going to default to first menu driver...\n"); menu_driver_ctx = (const menu_ctx_driver_t*) menu_driver_find_handle(0); if (!menu_driver_ctx) { retro_fail(1, "find_menu_driver()"); return false; } } } break; case RARCH_MENU_CTL_PLAYLIST_INIT: { const char *path = (const char*)data; if (string_is_empty(path)) return false; menu_driver_playlist = content_playlist_init(path, COLLECTION_SIZE); } break; case RARCH_MENU_CTL_PLAYLIST_GET: { content_playlist_t **playlist = (content_playlist_t**)data; if (!playlist) return false; *playlist = menu_driver_playlist; } break; case RARCH_MENU_CTL_SYSTEM_INFO_GET: { struct retro_system_info **system = (struct retro_system_info**)data; if (!system) return false; *system = &menu_driver_system; } break; case RARCH_MENU_CTL_SYSTEM_INFO_DEINIT: #ifdef HAVE_DYNAMIC libretro_free_system_info(&menu_driver_system); memset(&menu_driver_system, 0, sizeof(struct retro_system_info)); #endif break; case RARCH_MENU_CTL_RENDER_MESSAGEBOX: if (menu_driver_ctx->render_messagebox) menu_driver_ctx->render_messagebox(menu_userdata, menu_driver_data->menu_state.msg); break; case RARCH_MENU_CTL_BLIT_RENDER: if (menu_driver_ctx->render) menu_driver_ctx->render(menu_userdata); break; case RARCH_MENU_CTL_RENDER: if (!menu_driver_data) return false; if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER) != BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX)) BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER)) menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) && !string_is_empty(menu_driver_data->menu_state.msg)) { menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL); if (ui_companion_is_on_foreground()) { const ui_companion_driver_t *ui = ui_companion_get_ptr(); if (ui->render_messagebox) ui->render_messagebox(menu_driver_data->menu_state.msg); } } if (BIT64_GET(menu_driver_data->state, MENU_STATE_BLIT)) { menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL); menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL); } if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL)) menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL); menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL); menu_driver_data->state = 0; break; case RARCH_MENU_CTL_SHADER_DEINIT: #ifdef HAVE_SHADER_MANAGER if (menu_driver_shader) free(menu_driver_shader); menu_driver_shader = NULL; #endif break; case RARCH_MENU_CTL_SHADER_INIT: #ifdef HAVE_SHADER_MANAGER menu_driver_shader = (struct video_shader*) calloc(1, sizeof(struct video_shader)); if (!menu_driver_shader) return false; #endif break; case RARCH_MENU_CTL_SHADER_GET: { struct video_shader **shader = (struct video_shader**)data; if (!shader) return false; *shader = menu_driver_shader; } break; case RARCH_MENU_CTL_FRAME: if (!menu_driver_alive) return false; if (menu_driver_ctx->frame) menu_driver_ctx->frame(menu_userdata); break; case RARCH_MENU_CTL_SET_PREVENT_POPULATE: menu_driver_prevent_populate = true; break; case RARCH_MENU_CTL_UNSET_PREVENT_POPULATE: menu_driver_prevent_populate = false; break; case RARCH_MENU_CTL_IS_PREVENT_POPULATE: return menu_driver_prevent_populate; case RARCH_MENU_CTL_SET_TOGGLE: menu_driver_toggle(true); break; case RARCH_MENU_CTL_UNSET_TOGGLE: menu_driver_toggle(false); break; case RARCH_MENU_CTL_SET_ALIVE: menu_driver_alive = true; break; case RARCH_MENU_CTL_UNSET_ALIVE: menu_driver_alive = false; break; case RARCH_MENU_CTL_IS_ALIVE: return menu_driver_alive; case RARCH_MENU_CTL_SET_OWN_DRIVER: menu_driver_data_own = true; break; case RARCH_MENU_CTL_UNSET_OWN_DRIVER: if (!content_ctl(CONTENT_CTL_IS_INITED, NULL)) return false; menu_driver_data_own = false; break; case RARCH_MENU_CTL_SET_TEXTURE: if (menu_driver_ctx->set_texture) menu_driver_ctx->set_texture(); break; case RARCH_MENU_CTL_IS_SET_TEXTURE: if (!menu_driver_ctx) return false; return menu_driver_ctx->set_texture; case RARCH_MENU_CTL_OWNS_DRIVER: return menu_driver_data_own; case RARCH_MENU_CTL_DEINIT: menu_driver_ctl(RARCH_MENU_CTL_CONTEXT_DESTROY, NULL); if (menu_driver_ctl(RARCH_MENU_CTL_OWNS_DRIVER, NULL)) return true; if (menu_driver_data) { menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL); menu_shader_free(menu_driver_data); menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL); menu_navigation_ctl(MENU_NAVIGATION_CTL_DEINIT, NULL); if (menu_driver_ctx && menu_driver_ctx->free) menu_driver_ctx->free(menu_userdata); if (menu_userdata) free(menu_userdata); menu_userdata = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL); event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_FREE, NULL); free(menu_driver_data); } menu_driver_data = NULL; break; case RARCH_MENU_CTL_INIT: if (menu_driver_data) return true; menu_driver_data = (menu_handle_t*) menu_driver_ctx->init(&menu_userdata); if (!menu_driver_data || !menu_init(menu_driver_data)) { retro_fail(1, "init_menu()"); return false; } strlcpy(settings->menu.driver, menu_driver_ctx->ident, sizeof(settings->menu.driver)); if (menu_driver_ctx->lists_init) { if (!menu_driver_ctx->lists_init(menu_driver_data)) { retro_fail(1, "init_menu()"); return false; } } break; case RARCH_MENU_CTL_LOAD_NO_CONTENT_GET: { bool **ptr = (bool**)data; if (!ptr) return false; *ptr = (bool*)&menu_driver_load_no_content; } break; case RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT: return menu_driver_load_no_content; case RARCH_MENU_CTL_SET_LOAD_NO_CONTENT: menu_driver_load_no_content = true; break; case RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT: menu_driver_load_no_content = false; break; case RARCH_MENU_CTL_NAVIGATION_INCREMENT: if (menu_driver_ctx->navigation_increment) menu_driver_ctx->navigation_increment(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_DECREMENT: if (menu_driver_ctx->navigation_decrement) menu_driver_ctx->navigation_decrement(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_SET: { bool *scroll = (bool*)data; if (!scroll) return false; if (menu_driver_ctx->navigation_set) menu_driver_ctx->navigation_set(menu_userdata, *scroll); } break; case RARCH_MENU_CTL_NAVIGATION_SET_LAST: if (menu_driver_ctx->navigation_set_last) menu_driver_ctx->navigation_set_last(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_ASCEND_ALPHABET: { size_t *ptr_out = (size_t*)data; if (!ptr_out) return false; if (menu_driver_ctx->navigation_ascend_alphabet) menu_driver_ctx->navigation_ascend_alphabet( menu_userdata, ptr_out); } case RARCH_MENU_CTL_NAVIGATION_DESCEND_ALPHABET: { size_t *ptr_out = (size_t*)data; if (!ptr_out) return false; if (menu_driver_ctx->navigation_descend_alphabet) menu_driver_ctx->navigation_descend_alphabet( menu_userdata, ptr_out); } break; case RARCH_MENU_CTL_NAVIGATION_CLEAR: { bool *pending_push = (bool*)data; if (!pending_push) return false; if (menu_driver_ctx->navigation_clear) menu_driver_ctx->navigation_clear( menu_userdata, pending_push); } break; case RARCH_MENU_CTL_POPULATE_ENTRIES: { menu_displaylist_info_t *info = (menu_displaylist_info_t*)data; if (!info) return false; if (menu_driver_ctx->populate_entries) menu_driver_ctx->populate_entries( menu_userdata, info->path, info->label, info->type); } break; case RARCH_MENU_CTL_LIST_GET_ENTRY: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_entry) { list->entry = NULL; return false; } list->entry = menu_driver_ctx->list_get_entry(menu_userdata, list->type, list->idx); } break; case RARCH_MENU_CTL_LIST_GET_SIZE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_size) { list->size = 0; return false; } list->size = menu_driver_ctx->list_get_size(menu_userdata, list->type); } break; case RARCH_MENU_CTL_LIST_GET_SELECTION: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_selection) { list->selection = 0; return false; } list->selection = menu_driver_ctx->list_get_selection(menu_userdata); } break; case RARCH_MENU_CTL_LIST_FREE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (menu_driver_ctx) { if (menu_driver_ctx->list_free) menu_driver_ctx->list_free(list->list, list->idx, list->list_size); } if (list->list) { file_list_free_userdata (list->list, list->idx); file_list_free_actiondata(list->list, list->idx); } } break; case RARCH_MENU_CTL_LIST_PUSH: { menu_ctx_displaylist_t *disp_list = (menu_ctx_displaylist_t*)data; if (menu_driver_ctx->list_push) if (menu_driver_ctx->list_push(menu_driver_data, menu_userdata, disp_list->info, disp_list->type) == 0) return true; } return false; case RARCH_MENU_CTL_LIST_CLEAR: { file_list_t *list = (file_list_t*)data; if (!list) return false; if (menu_driver_ctx->list_clear) menu_driver_ctx->list_clear(list); } break; case RARCH_MENU_CTL_TOGGLE: { bool *latch = (bool*)data; if (!latch) return false; if (menu_driver_ctx->toggle) menu_driver_ctx->toggle(menu_userdata, *latch); } break; case RARCH_MENU_CTL_REFRESH: { #if 0 bool refresh = false; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); #endif } break; case RARCH_MENU_CTL_CONTEXT_RESET: if (!menu_driver_ctx || !menu_driver_ctx->context_reset) return false; menu_driver_ctx->context_reset(menu_userdata); break; case RARCH_MENU_CTL_CONTEXT_DESTROY: if (!menu_driver_ctx || !menu_driver_ctx->context_destroy) return false; menu_driver_ctx->context_destroy(menu_userdata); break; case RARCH_MENU_CTL_SHADER_MANAGER_INIT: menu_shader_manager_init(menu_driver_data); break; case RARCH_MENU_CTL_LIST_SET_SELECTION: { file_list_t *list = (file_list_t*)data; if (!list) return false; if (!menu_driver_ctx || !menu_driver_ctx->list_set_selection) return false; menu_driver_ctx->list_set_selection(menu_userdata, list); } break; case RARCH_MENU_CTL_LIST_CACHE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!list || !menu_driver_ctx || !menu_driver_ctx->list_cache) return false; menu_driver_ctx->list_cache(menu_userdata, list->type, list->action); } break; case RARCH_MENU_CTL_LIST_INSERT: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!list || !menu_driver_ctx || !menu_driver_ctx->list_insert) return false; menu_driver_ctx->list_insert(menu_userdata, list->list, list->path, list->label, list->idx); } break; case RARCH_MENU_CTL_LOAD_IMAGE: { menu_ctx_load_image_t *load_image_info = (menu_ctx_load_image_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->load_image) return false; return menu_driver_ctx->load_image(menu_userdata, load_image_info->data, load_image_info->type); } case RARCH_MENU_CTL_ITERATE: { bool retcode = false; menu_ctx_iterate_t *iterate = (menu_ctx_iterate_t*)data; if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL)) { bool msg_force = true; menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL); menu_entries_flush_stack(NULL, MENU_SETTINGS); menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); generic_action_ok_displaylist_push("", "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS); if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL); return false; } return true; } if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL); return false; } if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL); if (!event_cmd_ctl(EVENT_CMD_QUIT, NULL)) return false; return true; } if (!menu_driver_ctx || !menu_driver_ctx->iterate) return false; if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_ACTION, &retcode)) { iterate->action = pending_iter.action; pending_iter.action = MENU_ACTION_NOOP; } if (menu_driver_ctx->iterate(menu_driver_data, menu_userdata, iterate->action) == -1) return false; } break; case RARCH_MENU_CTL_ENVIRONMENT: { menu_ctx_environment_t *menu_environ = (menu_ctx_environment_t*)data; if (menu_driver_ctx->environ_cb) { if (menu_driver_ctx->environ_cb(menu_environ->type, menu_environ->data, menu_userdata) == 0) return true; } } return false; case RARCH_MENU_CTL_POINTER_TAP: { menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap) { point->retcode = 0; return false; } point->retcode = menu_driver_ctx->pointer_tap(menu_userdata, point->x, point->y, point->ptr, point->cbs, point->entry, point->action); } break; case RARCH_MENU_CTL_BIND_INIT: { menu_ctx_bind_t *bind = (menu_ctx_bind_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->bind_init) { bind->retcode = 0; return false; } bind->retcode = menu_driver_ctx->bind_init( bind->cbs, bind->path, bind->label, bind->type, bind->idx, bind->elem0, bind->elem1, bind->label_hash, bind->menu_label_hash); } break; default: case RARCH_MENU_CTL_NONE: break; } return true; }