void input_overlay_init(void) { input_overlay_free(); if (config_get_ptr()->input.overlay_enable) rarch_task_push_overlay_load_default(input_overlay_loaded, NULL); }
static void rarch_main_data_overlay_iterate(void) { if (g_runloop.is_idle) return; if (!driver.overlay) return; switch (driver.overlay->state) { case OVERLAY_STATUS_NONE: case OVERLAY_STATUS_ALIVE: break; case OVERLAY_STATUS_DEFERRED_LOAD: input_overlay_load_overlays(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_LOADING: input_overlay_load_overlays_iterate(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_LOADING_RESOLVE: input_overlay_load_overlays_resolve_iterate(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_DONE: input_overlay_new_done(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_ERROR: input_overlay_free(driver.overlay); break; default: break; } }
void rarch_main_data_overlay_iterate(bool is_thread) { #ifdef HAVE_THREADS if (is_thread) slock_lock(overlay_lock); #endif switch (input_overlay_status()) { case OVERLAY_STATUS_DEFERRED_LOAD: input_overlay_load_overlays(); break; case OVERLAY_STATUS_DEFERRED_LOADING_RESOLVE: input_overlay_load_overlays_resolve_iterate(); break; case OVERLAY_STATUS_DEFERRED_DONE: input_overlay_new_done(); break; case OVERLAY_STATUS_DEFERRED_ERROR: input_overlay_free(); break; default: case OVERLAY_STATUS_NONE: break; } #ifdef HAVE_THREADS if (is_thread) slock_unlock(overlay_lock); #endif }
void uninit_video_input(void) { #ifdef HAVE_OVERLAY if (driver.overlay) { input_overlay_free(driver.overlay); driver.overlay = NULL; memset(&driver.overlay_state, 0, sizeof(driver.overlay_state)); } #endif if (!driver.input_data_own && driver.input_data != driver.video_data && driver.input && driver.input->free) input_free_func(); if (!driver.video_data_own && driver.video_data && driver.video && driver.video->free) video_free_func(); deinit_pixel_converter(); rarch_deinit_filter(); deinit_shader_dir(); compute_monitor_fps_statistics(); }
void rarch_main_iterate_overlay_state(void) { switch (driver.overlay->state) { case OVERLAY_STATUS_NONE: case OVERLAY_STATUS_ALIVE: break; case OVERLAY_STATUS_DEFERRED_LOAD: input_overlay_load_overlays(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_LOADING: input_overlay_load_overlays_iterate(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_LOADING_RESOLVE: input_overlay_load_overlays_resolve_iterate(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_DONE: input_overlay_new_done(driver.overlay); break; case OVERLAY_STATUS_DEFERRED_ERROR: input_overlay_free(driver.overlay); break; default: break; } }
input_overlay_t *input_overlay_new(const char *overlay) { input_overlay_t *ol = (input_overlay_t*)calloc(1, sizeof(*ol)); if (!ol) goto error; ol->overlay_path = strdup(overlay); if (!ol->overlay_path) { free(ol); return NULL; } if (!driver.video->overlay_interface) { RARCH_ERR("Overlay interface is not present in video driver.\n"); goto error; } video_overlay_interface_func(&ol->iface); ol->iface_data = driver.video_data; if (!ol->iface) goto error; if (!input_overlay_load_overlays(ol, overlay)) goto error; ol->active = &ol->overlays[0]; input_overlay_load_active(ol); ol->iface->enable(ol->iface_data, true); ol->enable = true; input_overlay_set_alpha_mod(ol, g_settings.input.overlay_opacity); input_overlay_set_scale_factor(ol, g_settings.input.overlay_scale); ol->next_index = (ol->index + 1) % ol->size; return ol; error: input_overlay_free(ol); return NULL; }
input_overlay_t *input_overlay_new(const char *overlay) { input_overlay_t *ol = (input_overlay_t*)calloc(1, sizeof(*ol)); if (!ol) goto error; if (!driver.video->overlay_interface) { RARCH_ERR("Overlay interface is not present in video driver.\n"); goto error; } video_overlay_interface_func(&ol->iface); ol->iface_data = driver.video_data; if (!ol->iface) goto error; if (!input_overlay_load_overlays(ol, overlay)) goto error; ol->active = &ol->overlays[0]; ol->iface->load(ol->iface_data, ol->active->image, ol->active->width, ol->active->height); ol->iface->vertex_geom(ol->iface_data, ol->active->mod_x, ol->active->mod_y, ol->active->mod_w, ol->active->mod_h); ol->iface->full_screen(ol->iface_data, ol->active->full_screen); ol->iface->enable(ol->iface_data, true); ol->enable = true; input_overlay_set_alpha_mod(ol, g_settings.input.overlay_opacity); input_overlay_set_scale_factor(ol, 1.0f); ol->next_index = (ol->index + 1) % ol->size; return ol; error: input_overlay_free(ol); return NULL; }
/** * input_overlay_new: * @path : Path to overlay file. * @enable : Enable the overlay after initializing it? * * Creates and initializes an overlay handle. * * Returns: Overlay handle on success, otherwise NULL. **/ input_overlay_t *input_overlay_new(const char *path, bool enable, float opacity, float scale_factor) { input_overlay_t *ol = (input_overlay_t*)calloc(1, sizeof(*ol)); if (!ol) goto error; ol->overlay_path = strdup(path); if (!ol->overlay_path) { free(ol); return NULL; } if (!driver.video->overlay_interface) { RARCH_ERR("Overlay interface is not present in video driver.\n"); goto error; } if (driver.video && driver.video->overlay_interface) driver.video->overlay_interface(driver.video_data, &ol->iface); ol->iface_data = driver.video_data; if (!ol->iface) goto error; ol->state = OVERLAY_STATUS_DEFERRED_LOAD; ol->deferred.enable = enable; ol->deferred.opacity = opacity; ol->deferred.scale_factor = scale_factor; return ol; error: input_overlay_free(ol); 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; }
void init_video_input(void) { rarch_init_filter(g_extern.system.pix_fmt); init_shader_dir(); const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry; unsigned max_dim = max(geom->max_width, geom->max_height); unsigned scale = next_pow2(max_dim) / RARCH_SCALE_BASE; scale = max(scale, 1); if (g_extern.filter.filter) scale = g_extern.filter.scale; // Update core-dependent aspect ratio values. gfx_set_square_pixel_viewport(geom->base_width, geom->base_height); gfx_set_core_viewport(); gfx_set_config_viewport(); // Update CUSTOM viewport. rarch_viewport_t *custom_vp = &g_extern.console.screen.viewports.custom_vp; if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { float default_aspect = aspectratio_lut[ASPECT_RATIO_CORE].value; aspectratio_lut[ASPECT_RATIO_CUSTOM].value = (custom_vp->width && custom_vp->height) ? (float)custom_vp->width / custom_vp->height : default_aspect; } g_extern.system.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value; unsigned width; unsigned height; if (g_settings.video.fullscreen) { width = g_settings.video.fullscreen_x; height = g_settings.video.fullscreen_y; } else { if (g_settings.video.force_aspect) { // Do rounding here to simplify integer scale correctness. unsigned base_width = roundf(geom->base_height * g_extern.system.aspect_ratio); width = roundf(base_width * g_settings.video.xscale); height = roundf(geom->base_height * g_settings.video.yscale); } else { width = roundf(geom->base_width * g_settings.video.xscale); height = roundf(geom->base_height * g_settings.video.yscale); } } if (width && height) RARCH_LOG("Video @ %ux%u\n", width, height); else RARCH_LOG("Video @ fullscreen\n"); driver.display_type = RARCH_DISPLAY_NONE; driver.video_display = 0; driver.video_window = 0; if (!init_video_pixel_converter(RARCH_SCALE_BASE * scale)) { RARCH_ERR("Failed to initialize pixel converter.\n"); rarch_fail(1, "init_video_input()"); } video_info_t video = {0}; video.width = width; video.height = height; video.fullscreen = g_settings.video.fullscreen; video.vsync = g_settings.video.vsync && !g_extern.system.force_nonblock; video.force_aspect = g_settings.video.force_aspect; video.smooth = g_settings.video.smooth; video.input_scale = scale; video.rgb32 = g_extern.filter.filter ? g_extern.filter.out_rgb32 : (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); const input_driver_t *tmp = driver.input; find_video_driver(); // Need to grab the "real" video driver interface on a reinit. #ifdef HAVE_THREADS if (g_settings.video.threaded && !g_extern.system.hw_render_callback.context_type) // Can't do hardware rendering with threaded driver currently. { RARCH_LOG("Starting threaded video driver ...\n"); if (!rarch_threaded_video_init(&driver.video, &driver.video_data, &driver.input, &driver.input_data, driver.video, &video)) { RARCH_ERR("Cannot open threaded video driver ... Exiting ...\n"); rarch_fail(1, "init_video_input()"); } } else #endif driver.video_data = video_init_func(&video, &driver.input, &driver.input_data); if (driver.video_data == NULL) { RARCH_ERR("Cannot open video driver ... Exiting ...\n"); rarch_fail(1, "init_video_input()"); } driver.video_poke = NULL; if (driver.video->poke_interface) driver.video->poke_interface(driver.video_data, &driver.video_poke); // Force custom viewport to have sane parameters. if (driver.video->viewport_info && (!custom_vp->width || !custom_vp->height)) { custom_vp->width = width; custom_vp->height = height; driver.video->viewport_info(driver.video_data, custom_vp); } if (driver.video->set_rotation) video_set_rotation_func((g_settings.video.rotation + g_extern.system.rotation) % 4); #ifdef HAVE_X11 if (driver.display_type == RARCH_DISPLAY_X11) { RARCH_LOG("Suspending screensaver (X11).\n"); x11_suspend_screensaver(driver.video_window); } #endif // Video driver didn't provide an input driver so we use configured one. if (driver.input == NULL) { RARCH_LOG("Graphics driver did not initialize an input driver. Attempting to pick a suitable driver.\n"); if (tmp) driver.input = tmp; else find_input_driver(); if (driver.input) { driver.input_data = input_init_func(); if (!driver.input_data) { RARCH_ERR("Cannot initialize input driver. Exiting ...\n"); rarch_fail(1, "init_video_input()"); } } else { // This should never really happen as tmp (driver.input) is always found before this in find_driver_input(), // or we have aborted in a similar fashion anyways. rarch_fail(1, "init_video_input()"); } } #ifdef HAVE_OVERLAY if (driver.overlay) { input_overlay_free(driver.overlay); driver.overlay = NULL; } if (*g_settings.input.overlay) { driver.overlay = input_overlay_new(g_settings.input.overlay); if (!driver.overlay) RARCH_ERR("Failed to load overlay.\n"); } #endif g_extern.measure_data.frame_time_samples_count = 0; }
/** * 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; }
int menu_set_settings(unsigned setting, unsigned action) { unsigned port = rgui->current_pad; switch (setting) { case RGUI_START_SCREEN: if (action == RGUI_ACTION_OK) rgui_list_push(rgui->menu_stack, "", RGUI_START_SCREEN, 0); break; case RGUI_SETTINGS_REWIND_ENABLE: if (action == RGUI_ACTION_OK || action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT) { settings_set(1ULL << S_REWIND); if (g_settings.rewind_enable) rarch_init_rewind(); else rarch_deinit_rewind(); } else if (action == RGUI_ACTION_START) { g_settings.rewind_enable = false; rarch_deinit_rewind(); } break; #ifdef HAVE_SCREENSHOTS case RGUI_SETTINGS_GPU_SCREENSHOT: if (action == RGUI_ACTION_OK || action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT) g_settings.video.gpu_screenshot = !g_settings.video.gpu_screenshot; else if (action == RGUI_ACTION_START) g_settings.video.gpu_screenshot = true; break; #endif case RGUI_SETTINGS_REWIND_GRANULARITY: if (action == RGUI_ACTION_OK || action == RGUI_ACTION_RIGHT) settings_set(1ULL << S_REWIND_GRANULARITY_INCREMENT); else if (action == RGUI_ACTION_LEFT) settings_set(1ULL << S_REWIND_GRANULARITY_DECREMENT); else if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_REWIND_GRANULARITY); break; case RGUI_SETTINGS_CONFIG_SAVE_ON_EXIT: if (action == RGUI_ACTION_OK || action == RGUI_ACTION_RIGHT || action == RGUI_ACTION_LEFT) { g_extern.config_save_on_exit = !g_extern.config_save_on_exit; } else if (action == RGUI_ACTION_START) g_extern.config_save_on_exit = true; break; #if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) case RGUI_SETTINGS_SRAM_AUTOSAVE: if (action == RGUI_ACTION_OK || action == RGUI_ACTION_RIGHT || action == RGUI_ACTION_LEFT) { rarch_deinit_autosave(); g_settings.autosave_interval = (!g_settings.autosave_interval) * 10; if (g_settings.autosave_interval) rarch_init_autosave(); } else if (action == RGUI_ACTION_START) { rarch_deinit_autosave(); g_settings.autosave_interval = 0; } break; #endif case RGUI_SETTINGS_SAVESTATE_SAVE: case RGUI_SETTINGS_SAVESTATE_LOAD: if (action == RGUI_ACTION_OK) { if (setting == RGUI_SETTINGS_SAVESTATE_SAVE) rarch_save_state(); else rarch_load_state(); g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); return -1; } else if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_SAVE_STATE); else if (action == RGUI_ACTION_LEFT) settings_set(1ULL << S_SAVESTATE_DECREMENT); else if (action == RGUI_ACTION_RIGHT) settings_set(1ULL << S_SAVESTATE_INCREMENT); break; #ifdef HAVE_SCREENSHOTS case RGUI_SETTINGS_SCREENSHOT: if (action == RGUI_ACTION_OK) rarch_take_screenshot(); break; #endif case RGUI_SETTINGS_RESTART_GAME: if (action == RGUI_ACTION_OK) { rarch_game_reset(); g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); return -1; } break; case RGUI_SETTINGS_AUDIO_MUTE: if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_AUDIO_MUTE); else settings_set(1ULL << S_AUDIO_MUTE); break; case RGUI_SETTINGS_AUDIO_CONTROL_RATE_DELTA: if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_AUDIO_CONTROL_RATE); else if (action == RGUI_ACTION_LEFT) settings_set(1ULL << S_AUDIO_CONTROL_RATE_DECREMENT); else if (action == RGUI_ACTION_RIGHT) settings_set(1ULL << S_AUDIO_CONTROL_RATE_INCREMENT); break; case RGUI_SETTINGS_DEBUG_TEXT: if (action == RGUI_ACTION_START) g_settings.fps_show = false; else if (action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT) g_settings.fps_show = !g_settings.fps_show; break; case RGUI_SETTINGS_DISK_INDEX: { const struct retro_disk_control_callback *control = &g_extern.system.disk_control; unsigned num_disks = control->get_num_images(); unsigned current = control->get_image_index(); int step = 0; if (action == RGUI_ACTION_RIGHT || action == RGUI_ACTION_OK) step = 1; else if (action == RGUI_ACTION_LEFT) step = -1; if (step) { unsigned next_index = (current + num_disks + 1 + step) % (num_disks + 1); rarch_disk_control_set_eject(true, false); rarch_disk_control_set_index(next_index); rarch_disk_control_set_eject(false, false); } break; } case RGUI_SETTINGS_RESTART_EMULATOR: if (action == RGUI_ACTION_OK) { #if defined(GEKKO) && defined(HW_RVL) fill_pathname_join(g_extern.fullpath, default_paths.core_dir, SALAMANDER_FILE, sizeof(g_extern.fullpath)); #endif g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); g_extern.lifecycle_mode_state |= (1ULL << MODE_EXITSPAWN); return -1; } break; case RGUI_SETTINGS_RESUME_GAME: if (action == RGUI_ACTION_OK) { g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); return -1; } break; case RGUI_SETTINGS_QUIT_RARCH: if (action == RGUI_ACTION_OK) { g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); return -1; } break; case RGUI_SETTINGS_SAVE_CONFIG: if (action == RGUI_ACTION_OK) menu_save_new_config(); break; #ifdef HAVE_OVERLAY case RGUI_SETTINGS_OVERLAY_PRESET: switch (action) { case RGUI_ACTION_OK: rgui_list_push(rgui->menu_stack, g_extern.overlay_dir, setting, rgui->selection_ptr); rgui->selection_ptr = 0; rgui->need_refresh = true; break; #ifndef __QNX__ // FIXME: Why ifndef QNX? case RGUI_ACTION_START: if (driver.overlay) input_overlay_free(driver.overlay); driver.overlay = NULL; *g_settings.input.overlay = '\0'; break; #endif default: break; } break; case RGUI_SETTINGS_OVERLAY_OPACITY: { bool changed = true; switch (action) { case RGUI_ACTION_LEFT: settings_set(1ULL << S_INPUT_OVERLAY_OPACITY_DECREMENT); break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: settings_set(1ULL << S_INPUT_OVERLAY_OPACITY_INCREMENT); break; case RGUI_ACTION_START: settings_set(1ULL << S_DEF_INPUT_OVERLAY_OPACITY); break; default: changed = false; break; } if (changed && driver.overlay) input_overlay_set_alpha_mod(driver.overlay, g_settings.input.overlay_opacity); break; } case RGUI_SETTINGS_OVERLAY_SCALE: { bool changed = true; switch (action) { case RGUI_ACTION_LEFT: settings_set(1ULL << S_INPUT_OVERLAY_SCALE_DECREMENT); break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: settings_set(1ULL << S_INPUT_OVERLAY_SCALE_INCREMENT); break; case RGUI_ACTION_START: settings_set(1ULL << S_DEF_INPUT_OVERLAY_SCALE); break; default: changed = false; break; } if (changed && driver.overlay) input_overlay_set_scale_factor(driver.overlay, g_settings.input.overlay_scale); break; } #endif // controllers case RGUI_SETTINGS_BIND_PLAYER: if (action == RGUI_ACTION_START) rgui->current_pad = 0; else if (action == RGUI_ACTION_LEFT) { if (rgui->current_pad != 0) rgui->current_pad--; } else if (action == RGUI_ACTION_RIGHT) { if (rgui->current_pad < MAX_PLAYERS - 1) rgui->current_pad++; } #ifdef HAVE_RGUI if (port != rgui->current_pad) rgui->need_refresh = true; #endif port = rgui->current_pad; break; case RGUI_SETTINGS_BIND_DEVICE: // If set_keybinds is supported, we do it more fancy, and scroll through // a list of supported devices directly. if (driver.input->set_keybinds) { g_settings.input.device[port] += DEVICE_LAST; if (action == RGUI_ACTION_START) g_settings.input.device[port] = 0; else if (action == RGUI_ACTION_LEFT) g_settings.input.device[port]--; else if (action == RGUI_ACTION_RIGHT) g_settings.input.device[port]++; // DEVICE_LAST can be 0, avoid modulo. if (g_settings.input.device[port] >= DEVICE_LAST) g_settings.input.device[port] -= DEVICE_LAST; unsigned keybind_action = (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BINDS); driver.input->set_keybinds(driver.input_data, g_settings.input.device[port], port, 0, keybind_action); } else { // When only straight g_settings.input.joypad_map[] style // mapping is supported. int *p = &g_settings.input.joypad_map[port]; if (action == RGUI_ACTION_START) *p = port; else if (action == RGUI_ACTION_LEFT) (*p)--; else if (action == RGUI_ACTION_RIGHT) (*p)++; if (*p < -1) *p = -1; else if (*p >= MAX_PLAYERS) *p = MAX_PLAYERS - 1; } break; case RGUI_SETTINGS_BIND_DEVICE_TYPE: { static const unsigned device_types[] = { RETRO_DEVICE_NONE, RETRO_DEVICE_JOYPAD, RETRO_DEVICE_ANALOG, RETRO_DEVICE_MOUSE, RETRO_DEVICE_JOYPAD_MULTITAP, RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE, RETRO_DEVICE_LIGHTGUN_JUSTIFIER, RETRO_DEVICE_LIGHTGUN_JUSTIFIERS, }; unsigned current_device, current_index, i; current_device = g_settings.input.libretro_device[port]; current_index = 0; for (i = 0; i < ARRAY_SIZE(device_types); i++) { if (current_device == device_types[i]) { current_index = i; break; } } bool updated = true; switch (action) { case RGUI_ACTION_START: current_device = RETRO_DEVICE_JOYPAD; break; case RGUI_ACTION_LEFT: current_device = device_types[(current_index + ARRAY_SIZE(device_types) - 1) % ARRAY_SIZE(device_types)]; break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: current_device = device_types[(current_index + 1) % ARRAY_SIZE(device_types)]; break; default: updated = false; } if (updated) { g_settings.input.libretro_device[port] = current_device; pretro_set_controller_port_device(port, current_device); } break; } case RGUI_SETTINGS_CUSTOM_BIND_ALL: if (action == RGUI_ACTION_OK) { rgui->binds.target = &g_settings.input.binds[port][0]; rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN; rgui->binds.last = RGUI_SETTINGS_BIND_LAST; rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); menu_poll_bind_get_rested_axes(&rgui->binds); menu_poll_bind_state(&rgui->binds); } break; case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL: if (action == RGUI_ACTION_OK) { unsigned i; struct retro_keybind *target = &g_settings.input.binds[port][0]; rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN; rgui->binds.last = RGUI_SETTINGS_BIND_LAST; for (i = RGUI_SETTINGS_BIND_BEGIN; i <= RGUI_SETTINGS_BIND_LAST; i++, target++) { target->joykey = NO_BTN; target->joyaxis = AXIS_NONE; } } break; case RGUI_SETTINGS_BIND_UP: case RGUI_SETTINGS_BIND_DOWN: case RGUI_SETTINGS_BIND_LEFT: case RGUI_SETTINGS_BIND_RIGHT: case RGUI_SETTINGS_BIND_A: case RGUI_SETTINGS_BIND_B: case RGUI_SETTINGS_BIND_X: case RGUI_SETTINGS_BIND_Y: case RGUI_SETTINGS_BIND_START: case RGUI_SETTINGS_BIND_SELECT: case RGUI_SETTINGS_BIND_L: case RGUI_SETTINGS_BIND_R: case RGUI_SETTINGS_BIND_L2: case RGUI_SETTINGS_BIND_R2: case RGUI_SETTINGS_BIND_L3: case RGUI_SETTINGS_BIND_R3: case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_PLUS: case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_MINUS: case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_PLUS: case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_MINUS: case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_PLUS: case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_MINUS: case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_PLUS: case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_MINUS: case RGUI_SETTINGS_BIND_MENU_TOGGLE: if (driver.input->set_keybinds) { unsigned keybind_action = KEYBINDS_ACTION_NONE; if (action == RGUI_ACTION_START) keybind_action = (1ULL << KEYBINDS_ACTION_SET_DEFAULT_BIND); // FIXME: The array indices here look totally wrong ... Fixed it so it looks kind of sane for now. if (keybind_action != KEYBINDS_ACTION_NONE) driver.input->set_keybinds(driver.input_data, g_settings.input.device[port], port, setting - RGUI_SETTINGS_BIND_BEGIN, keybind_action); } else { struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_BEGIN]; if (action == RGUI_ACTION_OK) { rgui->binds.begin = setting; rgui->binds.last = setting; rgui->binds.target = bind; rgui->binds.player = port; rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); menu_poll_bind_get_rested_axes(&rgui->binds); menu_poll_bind_state(&rgui->binds); } else if (action == RGUI_ACTION_START) { bind->joykey = NO_BTN; bind->joyaxis = AXIS_NONE; } } break; case RGUI_BROWSER_DIR_PATH: if (action == RGUI_ACTION_START) { *g_settings.rgui_browser_directory = '\0'; *rgui->base_path = '\0'; } break; #ifdef HAVE_SCREENSHOTS case RGUI_SCREENSHOT_DIR_PATH: if (action == RGUI_ACTION_START) *g_settings.screenshot_directory = '\0'; break; #endif case RGUI_SAVEFILE_DIR_PATH: if (action == RGUI_ACTION_START) *g_extern.savefile_dir = '\0'; break; #ifdef HAVE_OVERLAY case RGUI_OVERLAY_DIR_PATH: if (action == RGUI_ACTION_START) *g_extern.overlay_dir = '\0'; break; #endif case RGUI_SAVESTATE_DIR_PATH: if (action == RGUI_ACTION_START) *g_extern.savestate_dir = '\0'; break; #ifdef HAVE_DYNAMIC case RGUI_LIBRETRO_DIR_PATH: if (action == RGUI_ACTION_START) { *rgui->libretro_dir = '\0'; menu_init_core_info(rgui); } break; #endif case RGUI_LIBRETRO_INFO_DIR_PATH: if (action == RGUI_ACTION_START) { *g_settings.libretro_info_path = '\0'; menu_init_core_info(rgui); } break; case RGUI_CONFIG_DIR_PATH: if (action == RGUI_ACTION_START) *g_settings.rgui_config_directory = '\0'; break; case RGUI_SHADER_DIR_PATH: if (action == RGUI_ACTION_START) *g_settings.video.shader_dir = '\0'; break; case RGUI_SYSTEM_DIR_PATH: if (action == RGUI_ACTION_START) *g_settings.system_directory = '\0'; break; case RGUI_SETTINGS_VIDEO_ROTATION: if (action == RGUI_ACTION_START) { settings_set(1ULL << S_DEF_ROTATION); video_set_rotation_func((g_settings.video.rotation + g_extern.system.rotation) % 4); } else if (action == RGUI_ACTION_LEFT) { settings_set(1ULL << S_ROTATION_DECREMENT); video_set_rotation_func((g_settings.video.rotation + g_extern.system.rotation) % 4); } else if (action == RGUI_ACTION_RIGHT) { settings_set(1ULL << S_ROTATION_INCREMENT); video_set_rotation_func((g_settings.video.rotation + g_extern.system.rotation) % 4); } break; case RGUI_SETTINGS_VIDEO_FILTER: if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_HW_TEXTURE_FILTER); else settings_set(1ULL << S_HW_TEXTURE_FILTER); if (driver.video_poke->set_filtering) driver.video_poke->set_filtering(driver.video_data, 1, g_settings.video.smooth); break; case RGUI_SETTINGS_VIDEO_GAMMA: if (action == RGUI_ACTION_START) { g_extern.console.screen.gamma_correction = 0; if (driver.video_poke->apply_state_changes) driver.video_poke->apply_state_changes(driver.video_data); } else if (action == RGUI_ACTION_LEFT) { if(g_extern.console.screen.gamma_correction > 0) { g_extern.console.screen.gamma_correction--; if (driver.video_poke->apply_state_changes) driver.video_poke->apply_state_changes(driver.video_data); } } else if (action == RGUI_ACTION_RIGHT) { if(g_extern.console.screen.gamma_correction < MAX_GAMMA_SETTING) { g_extern.console.screen.gamma_correction++; if (driver.video_poke->apply_state_changes) driver.video_poke->apply_state_changes(driver.video_data); } } break; case RGUI_SETTINGS_VIDEO_INTEGER_SCALE: if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_SCALE_INTEGER); else if (action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT || action == RGUI_ACTION_OK) settings_set(1ULL << S_SCALE_INTEGER_TOGGLE); if (driver.video_poke->apply_state_changes) driver.video_poke->apply_state_changes(driver.video_data); break; case RGUI_SETTINGS_VIDEO_ASPECT_RATIO: if (action == RGUI_ACTION_START) settings_set(1ULL << S_DEF_ASPECT_RATIO); else if (action == RGUI_ACTION_LEFT) settings_set(1ULL << S_ASPECT_RATIO_DECREMENT); else if (action == RGUI_ACTION_RIGHT) settings_set(1ULL << S_ASPECT_RATIO_INCREMENT); if (driver.video_poke->set_aspect_ratio) driver.video_poke->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx); break; case RGUI_SETTINGS_TOGGLE_FULLSCREEN: if (action == RGUI_ACTION_OK) rarch_set_fullscreen(!g_settings.video.fullscreen); break; #if defined(GEKKO) case RGUI_SETTINGS_VIDEO_RESOLUTION: if (action == RGUI_ACTION_LEFT) { if(rgui_current_gx_resolution > 0) { rgui_current_gx_resolution--; gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution][0], rgui_gx_resolutions[rgui_current_gx_resolution][1]); } } else if (action == RGUI_ACTION_RIGHT) { if (rgui_current_gx_resolution < GX_RESOLUTIONS_LAST - 1) { #ifdef HW_RVL if ((rgui_current_gx_resolution + 1) > GX_RESOLUTIONS_640_480) if (CONF_GetVideo() != CONF_VIDEO_PAL) return 0; #endif rgui_current_gx_resolution++; gx_set_video_mode(rgui_gx_resolutions[rgui_current_gx_resolution][0], rgui_gx_resolutions[rgui_current_gx_resolution][1]); } } break; #elif defined(__CELLOS_LV2__) case RGUI_SETTINGS_VIDEO_RESOLUTION: if (action == RGUI_ACTION_LEFT) settings_set(1ULL << S_RESOLUTION_PREVIOUS); else if (action == RGUI_ACTION_RIGHT) settings_set(1ULL << S_RESOLUTION_NEXT); else if (action == RGUI_ACTION_OK) { if (g_extern.console.screen.resolutions.list[g_extern.console.screen.resolutions.current.idx] == CELL_VIDEO_OUT_RESOLUTION_576) { if (g_extern.console.screen.pal_enable) g_extern.lifecycle_mode_state |= (1ULL<< MODE_VIDEO_PAL_ENABLE); } else { g_extern.lifecycle_mode_state &= ~(1ULL << MODE_VIDEO_PAL_ENABLE); g_extern.lifecycle_mode_state &= ~(1ULL << MODE_VIDEO_PAL_TEMPORAL_ENABLE); } driver.video->restart(); rgui_init_textures(); } break; #endif #ifdef HW_RVL case RGUI_SETTINGS_VIDEO_SOFT_FILTER: if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE)) g_extern.lifecycle_mode_state &= ~(1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE); else g_extern.lifecycle_mode_state |= (1ULL << MODE_VIDEO_SOFT_FILTER_ENABLE); if (driver.video_poke->apply_state_changes) driver.video_poke->apply_state_changes(driver.video_data); break; #endif case RGUI_SETTINGS_VIDEO_VSYNC: switch (action) { case RGUI_ACTION_START: settings_set(1ULL << S_DEF_VIDEO_VSYNC); break; case RGUI_ACTION_LEFT: case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: settings_set(1ULL << S_VIDEO_VSYNC_TOGGLE); break; default: break; } break; case RGUI_SETTINGS_VIDEO_HARD_SYNC: switch (action) { case RGUI_ACTION_START: g_settings.video.hard_sync = false; break; case RGUI_ACTION_LEFT: case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: g_settings.video.hard_sync = !g_settings.video.hard_sync; break; default: break; } break; case RGUI_SETTINGS_VIDEO_BLACK_FRAME_INSERTION: switch (action) { case RGUI_ACTION_START: g_settings.video.black_frame_insertion = false; break; case RGUI_ACTION_LEFT: case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: g_settings.video.black_frame_insertion = !g_settings.video.black_frame_insertion; break; default: break; } break; case RGUI_SETTINGS_VIDEO_CROP_OVERSCAN: switch (action) { case RGUI_ACTION_START: g_settings.video.crop_overscan = true; break; case RGUI_ACTION_LEFT: case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: g_settings.video.crop_overscan = !g_settings.video.crop_overscan; break; default: break; } break; case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X: case RGUI_SETTINGS_VIDEO_WINDOW_SCALE_Y: { float *scale = setting == RGUI_SETTINGS_VIDEO_WINDOW_SCALE_X ? &g_settings.video.xscale : &g_settings.video.yscale; float old_scale = *scale; switch (action) { case RGUI_ACTION_START: *scale = 3.0f; break; case RGUI_ACTION_LEFT: *scale -= 1.0f; break; case RGUI_ACTION_RIGHT: *scale += 1.0f; break; default: break; } *scale = roundf(*scale); *scale = max(*scale, 1.0f); if (old_scale != *scale && !g_settings.video.fullscreen) rarch_set_fullscreen(g_settings.video.fullscreen); // Reinit video driver. break; } #ifdef HAVE_THREADS case RGUI_SETTINGS_VIDEO_THREADED: { bool old = g_settings.video.threaded; if (action == RGUI_ACTION_OK || action == RGUI_ACTION_LEFT || action == RGUI_ACTION_RIGHT) g_settings.video.threaded = !g_settings.video.threaded; else if (action == RGUI_ACTION_START) g_settings.video.threaded = false; if (g_settings.video.threaded != old) rarch_set_fullscreen(g_settings.video.fullscreen); // Reinit video driver. break; } #endif case RGUI_SETTINGS_VIDEO_SWAP_INTERVAL: { unsigned old = g_settings.video.swap_interval; switch (action) { case RGUI_ACTION_START: g_settings.video.swap_interval = 1; break; case RGUI_ACTION_LEFT: g_settings.video.swap_interval--; break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: g_settings.video.swap_interval++; break; default: break; } g_settings.video.swap_interval = min(g_settings.video.swap_interval, 4); g_settings.video.swap_interval = max(g_settings.video.swap_interval, 1); if (old != g_settings.video.swap_interval && driver.video && driver.video_data) video_set_nonblock_state_func(false); // This will update the current swap interval. Since we're in RGUI now, always apply VSync. break; } case RGUI_SETTINGS_VIDEO_HARD_SYNC_FRAMES: switch (action) { case RGUI_ACTION_START: g_settings.video.hard_sync_frames = 0; break; case RGUI_ACTION_LEFT: if (g_settings.video.hard_sync_frames > 0) g_settings.video.hard_sync_frames--; break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: if (g_settings.video.hard_sync_frames < 3) g_settings.video.hard_sync_frames++; break; default: break; } break; case RGUI_SETTINGS_VIDEO_REFRESH_RATE_AUTO: switch (action) { case RGUI_ACTION_START: g_extern.measure_data.frame_time_samples_count = 0; break; case RGUI_ACTION_OK: { double refresh_rate = 0.0; double deviation = 0.0; unsigned sample_points = 0; if (driver_monitor_fps_statistics(&refresh_rate, &deviation, &sample_points)) { driver_set_monitor_refresh_rate(refresh_rate); // Incase refresh rate update forced non-block video. video_set_nonblock_state_func(false); } break; } default: break; } break; #ifdef HAVE_SHADER_MANAGER case RGUI_SETTINGS_SHADER_PASSES: switch (action) { case RGUI_ACTION_START: rgui->shader.passes = 0; break; case RGUI_ACTION_LEFT: if (rgui->shader.passes) rgui->shader.passes--; break; case RGUI_ACTION_RIGHT: case RGUI_ACTION_OK: if (rgui->shader.passes < RGUI_MAX_SHADERS) rgui->shader.passes++; break; default: break; } #ifndef HAVE_RMENU rgui->need_refresh = true; #endif break; case RGUI_SETTINGS_SHADER_APPLY: { if (!driver.video->set_shader || action != RGUI_ACTION_OK) return 0; RARCH_LOG("Applying shader ...\n"); enum rarch_shader_type type = shader_manager_get_type(&rgui->shader); if (rgui->shader.passes && type != RARCH_SHADER_NONE) { const char *conf_path = type == RARCH_SHADER_GLSL ? rgui->default_glslp : rgui->default_cgp; char config_directory[PATH_MAX]; if (*g_extern.config_path) fill_pathname_basedir(config_directory, g_extern.config_path, sizeof(config_directory)); else *config_directory = '\0'; char cgp_path[PATH_MAX]; const char *dirs[] = { g_settings.video.shader_dir, g_settings.rgui_config_directory, config_directory, }; config_file_t *conf = config_file_new(NULL); if (!conf) return 0; gfx_shader_write_conf_cgp(conf, &rgui->shader); bool ret = false; unsigned d; for (d = 0; d < ARRAY_SIZE(dirs); d++) { if (!*dirs[d]) continue; fill_pathname_join(cgp_path, dirs[d], conf_path, sizeof(cgp_path)); if (config_file_write(conf, cgp_path)) { RARCH_LOG("Saved shader preset to %s.\n", cgp_path); shader_manager_set_preset(NULL, type, cgp_path); ret = true; break; } else RARCH_LOG("Failed writing shader preset to %s.\n", cgp_path); } config_file_free(conf); if (!ret) RARCH_ERR("Failed to save shader preset. Make sure config directory and/or shader dir are writable.\n"); } else { type = gfx_shader_parse_type("", DEFAULT_SHADER_TYPE); if (type == RARCH_SHADER_NONE) { #if defined(HAVE_GLSL) type = RARCH_SHADER_GLSL; #elif defined(HAVE_CG) || defined(HAVE_HLSL) type = RARCH_SHADER_CG; #endif } shader_manager_set_preset(NULL, type, NULL); } } break; #endif default: break; } return 0; }