/** * netplay_post_frame_net: * @netplay : pointer to netplay object * * Post-frame for Netplay (normal version). * We check if we have new input and replay from recorded input. **/ static void netplay_post_frame_net(netplay_t *netplay) { netplay->frame_count++; /* Nothing to do... */ if (netplay->other_frame_count == netplay->read_frame_count) return; /* Skip ahead if we predicted correctly. * Skip until our simulation failed. */ while (netplay->other_frame_count < netplay->read_frame_count) { const struct delta_frame *ptr = &netplay->buffer[netplay->other_ptr]; if ((ptr->simulated_input_state != ptr->real_input_state) && !ptr->used_real) break; netplay->other_ptr = NEXT_PTR(netplay->other_ptr); netplay->other_frame_count++; } if (netplay->other_frame_count < netplay->read_frame_count) { bool first = true; /* Replay frames. */ netplay->is_replay = true; netplay->tmp_ptr = netplay->other_ptr; netplay->tmp_frame_count = netplay->other_frame_count; core.retro_unserialize(netplay->buffer[netplay->other_ptr].state, netplay->state_size); while (first || (netplay->tmp_ptr != netplay->self_ptr)) { core.retro_serialize(netplay->buffer[netplay->tmp_ptr].state, netplay->state_size); #if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) lock_autosave(); #endif core.retro_run(); #if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) unlock_autosave(); #endif netplay->tmp_ptr = NEXT_PTR(netplay->tmp_ptr); netplay->tmp_frame_count++; first = false; } netplay->other_ptr = netplay->read_ptr; netplay->other_frame_count = netplay->read_frame_count; netplay->is_replay = false; } }
static void netplay_post_frame_net(netplay_t *handle) { handle->frame_count++; // Nothing to do... if (handle->other_frame_count == handle->read_frame_count) return; // Skip ahead if we predicted correctly. Skip until our simulation failed. while (handle->other_frame_count < handle->read_frame_count) { const struct delta_frame *ptr = &handle->buffer[handle->other_ptr]; if ((ptr->simulated_input_state != ptr->real_input_state) && !ptr->used_real) break; handle->other_ptr = NEXT_PTR(handle->other_ptr); handle->other_frame_count++; } if (handle->other_frame_count < handle->read_frame_count) { // Replay frames handle->is_replay = true; handle->tmp_ptr = handle->other_ptr; handle->tmp_frame_count = handle->other_frame_count; pretro_unserialize(handle->buffer[handle->other_ptr].state, handle->state_size); bool first = true; while (first || (handle->tmp_ptr != handle->self_ptr)) { pretro_serialize(handle->buffer[handle->tmp_ptr].state, handle->state_size); #if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) lock_autosave(); #endif pretro_run(); #if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE) unlock_autosave(); #endif handle->tmp_ptr = NEXT_PTR(handle->tmp_ptr); handle->tmp_frame_count++; first = false; } handle->other_ptr = handle->read_ptr; handle->other_frame_count = handle->read_frame_count; handle->is_replay = false; } }
/** * runloop_iterate: * * Run Libretro core in RetroArch for one frame. * * Returns: 0 on success, 1 if we have to wait until button input in order * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. **/ int runloop_iterate(unsigned *sleep_ms) { unsigned i; event_cmd_state_t cmd; event_cmd_state_t *cmd_ptr = &cmd; retro_time_t current, target, to_sleep_ms; static retro_usec_t frame_time_last = 0; static retro_time_t frame_limit_minimum_time = 0.0; static retro_time_t frame_limit_last_time = 0.0; static retro_input_t last_input = 0; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); rarch_system_info_t *system = NULL; cmd.state[1] = last_input; cmd.state[0] = input_keys_pressed(); last_input = cmd.state[0]; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); if (runloop_ctl(RUNLOOP_CTL_IS_FRAME_TIME_LAST, NULL)) { frame_time_last = 0; runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_TIME_LAST, NULL); } if (runloop_ctl(RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT, NULL)) { struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); float fastforward_ratio = (settings->fastforward_ratio == 0.0f) ? 1.0f : settings->fastforward_ratio; frame_limit_last_time = retro_get_time_usec(); frame_limit_minimum_time = (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * fastforward_ratio)); runloop_ctl(RUNLOOP_CTL_UNSET_FRAME_LIMIT, NULL); } if (input_driver_ctl(RARCH_INPUT_CTL_IS_FLUSHING_INPUT, NULL)) { input_driver_ctl(RARCH_INPUT_CTL_UNSET_FLUSHING_INPUT, NULL); if (cmd.state[0]) { cmd.state[0] = 0; /* If core was paused before entering menu, evoke * pause toggle to wake it up. */ if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) BIT64_SET(cmd.state[0], RARCH_PAUSE_TOGGLE); input_driver_ctl(RARCH_INPUT_CTL_SET_FLUSHING_INPUT, NULL); } } if (system->frame_time.callback) { /* Updates frame timing if frame timing callback is in use by the core. * Limits frame time if fast forward ratio throttle is enabled. */ bool is_slowmotion; retro_time_t current = retro_get_time_usec(); retro_time_t delta = current - frame_time_last; bool is_locked_fps = (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) || input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) | !!recording_driver_get_data_ptr(); runloop_ctl(RUNLOOP_CTL_IS_SLOWMOTION, &is_slowmotion); if (!frame_time_last || is_locked_fps) delta = system->frame_time.reference; if (!is_locked_fps && is_slowmotion) delta /= settings->slowmotion_ratio; frame_time_last = current; if (is_locked_fps) frame_time_last = 0; system->frame_time.callback(delta); } cmd.state[2] = cmd.state[0] & ~cmd.state[1]; /* trigger */ if (runloop_cmd_triggered(cmd_ptr, RARCH_OVERLAY_NEXT)) event_command(EVENT_CMD_OVERLAY_NEXT); if (runloop_cmd_triggered(cmd_ptr, RARCH_FULLSCREEN_TOGGLE_KEY)) { bool fullscreen_toggled = !runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); #ifdef HAVE_MENU fullscreen_toggled = fullscreen_toggled || menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL); #endif if (fullscreen_toggled) event_command(EVENT_CMD_FULLSCREEN_TOGGLE); } if (runloop_cmd_triggered(cmd_ptr, RARCH_GRAB_MOUSE_TOGGLE)) event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE); #ifdef HAVE_MENU if (runloop_cmd_menu_press(cmd_ptr) || (global->inited.core.type == CORE_TYPE_DUMMY)) { if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY)) rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); } else rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); } #endif #ifdef HAVE_OVERLAY runloop_iterate_linefeed_overlay(settings); #endif if (runloop_iterate_time_to_exit(runloop_cmd_press(cmd_ptr, RARCH_QUIT_KEY)) != 1) { frame_limit_last_time = 0.0; return -1; } #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { bool focused = runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL) && !ui_companion_is_on_foreground(); bool is_idle = runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL); if (menu_driver_iterate((enum menu_action)menu_input_frame_retropad(cmd.state[0], cmd.state[2])) == -1) rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); if (focused || !is_idle) menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL); if (!focused || is_idle) { *sleep_ms = 10; return 1; } goto end; } #endif if (!runloop_ctl(RUNLOOP_CTL_CHECK_STATE, &cmd)) { /* RetroArch has been paused. */ retro_ctx.poll_cb(); *sleep_ms = 10; return 1; } #if defined(HAVE_THREADS) lock_autosave(); #endif #ifdef HAVE_NETPLAY netplay_driver_ctl(RARCH_NETPLAY_CTL_PRE_FRAME, NULL); #endif if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_START, NULL); if (system->camera_callback.caps) driver_camera_poll(); /* Update binds for analog dpad modes. */ for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_push_analog_dpad(settings->input.binds[i], settings->input.analog_dpad_mode[i]); input_push_analog_dpad(settings->input.autoconf_binds[i], settings->input.analog_dpad_mode[i]); } if ((settings->video.frame_delay > 0) && !input_driver_ctl(RARCH_INPUT_CTL_IS_NONBLOCK_STATE, NULL)) retro_sleep(settings->video.frame_delay); /* Run libretro for one frame. */ core.retro_run(); #ifdef HAVE_CHEEVOS /* Test the achievements. */ cheevos_test(); #endif for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_pop_analog_dpad(settings->input.binds[i]); input_pop_analog_dpad(settings->input.autoconf_binds[i]); } if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) bsv_movie_ctl(BSV_MOVIE_CTL_SET_FRAME_END, NULL); #ifdef HAVE_NETPLAY netplay_driver_ctl(RARCH_NETPLAY_CTL_POST_FRAME, NULL); #endif #if defined(HAVE_THREADS) unlock_autosave(); #endif #ifdef HAVE_MENU end: #endif if (!settings->fastforward_ratio) return 0; current = retro_get_time_usec(); target = frame_limit_last_time + frame_limit_minimum_time; to_sleep_ms = (target - current) / 1000; if (to_sleep_ms > 0) { *sleep_ms = (unsigned)to_sleep_ms; /* Combat jitter a bit. */ frame_limit_last_time += frame_limit_minimum_time; return 1; } frame_limit_last_time = retro_get_time_usec(); return 0; }
/** * rarch_main_iterate: * * Run Libretro core in RetroArch for one frame. * * Returns: 0 on success, 1 if we have to wait until button input in order * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. **/ int rarch_main_iterate(unsigned *sleep_ms) { int ret; unsigned i; retro_input_t trigger_input; event_cmd_state_t cmd; retro_time_t current, target, to_sleep_ms; static retro_input_t last_input = 0; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); retro_input_t input = input_keys_pressed(driver, settings, global); rarch_system_info_t *system = rarch_system_info_get_ptr(); retro_input_t old_input = last_input; last_input = input; if (driver->flushing_input) { driver->flushing_input = false; if (input) { input = 0; /* If core was paused before entering menu, evoke * pause toggle to wake it up. */ if (main_is_paused) BIT64_SET(input, RARCH_PAUSE_TOGGLE); driver->flushing_input = true; } } trigger_input = input & ~old_input; rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input); if (system->frame_time.callback) { /* Updates frame timing if frame timing callback is in use by the core. * Limits frame time if fast forward ratio throttle is enabled. */ retro_time_t current = retro_get_time_usec(); retro_time_t delta = current - system->frame_time_last; bool is_locked_fps = (main_is_paused || driver->nonblock_state) | !!driver->recording_data; if (!system->frame_time_last || is_locked_fps) delta = system->frame_time.reference; if (!is_locked_fps && main_is_slowmotion) delta /= settings->slowmotion_ratio; system->frame_time_last = current; if (is_locked_fps) system->frame_time_last = 0; system->frame_time.callback(delta); } if (cmd.overlay_next_pressed) event_command(EVENT_CMD_OVERLAY_NEXT); if (!main_is_paused || menu_driver_alive()) { if (cmd.fullscreen_toggle) event_command(EVENT_CMD_FULLSCREEN_TOGGLE); } if (cmd.grab_mouse_pressed) event_command(EVENT_CMD_GRAB_MOUSE_TOGGLE); #ifdef HAVE_MENU if (cmd.menu_pressed || (global->inited.core.type == CORE_TYPE_DUMMY)) { if (menu_driver_alive()) { if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY)) rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL); } else rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL); } #endif #ifdef HAVE_OVERLAY rarch_main_iterate_linefeed_overlay(driver, settings); #endif ret = rarch_main_iterate_time_to_exit(&cmd); if (ret != 1) return -1; #ifdef HAVE_MENU if (menu_driver_alive()) { if (menu_driver_iterate((enum menu_action)menu_input_frame(input, trigger_input)) == -1) rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL); if (!input && settings->menu.pause_libretro) return 1; goto end; } #endif if (!rarch_main_ctl(RARCH_MAIN_CTL_CHECK_STATE, &cmd)) { /* RetroArch has been paused. */ driver->retro_ctx.poll_cb(); *sleep_ms = 10; return 1; } #if defined(HAVE_THREADS) lock_autosave(); #endif #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_pre_frame((netplay_t*)driver->netplay_data); #endif if (global->bsv.movie) bsv_movie_set_frame_start(global->bsv.movie); if (system->camera_callback.caps) driver_camera_poll(); /* Update binds for analog dpad modes. */ for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_push_analog_dpad(settings->input.binds[i], settings->input.analog_dpad_mode[i]); input_push_analog_dpad(settings->input.autoconf_binds[i], settings->input.analog_dpad_mode[i]); } if ((settings->video.frame_delay > 0) && !driver->nonblock_state) retro_sleep(settings->video.frame_delay); /* Run libretro for one frame. */ core.retro_run(); #ifdef HAVE_CHEEVOS /* Test the achievements. */ cheevos_test(); #endif for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_pop_analog_dpad(settings->input.binds[i]); input_pop_analog_dpad(settings->input.autoconf_binds[i]); } if (global->bsv.movie) bsv_movie_set_frame_end(global->bsv.movie); #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_post_frame((netplay_t*)driver->netplay_data); #endif #if defined(HAVE_THREADS) unlock_autosave(); #endif #ifdef HAVE_MENU end: #endif if (!settings->fastforward_ratio) return 0; current = retro_get_time_usec(); target = frame_limit_last_time + frame_limit_minimum_time; to_sleep_ms = (target - current) / 1000; if (to_sleep_ms > 0) { *sleep_ms = (unsigned)to_sleep_ms; /* Combat jitter a bit. */ frame_limit_last_time += frame_limit_minimum_time; return 1; } frame_limit_last_time = retro_get_time_usec(); return 0; }
/** * rarch_main_iterate: * * Run Libretro core in RetroArch for one frame. * * Returns: 0 on success, 1 if we have to wait until button input in order * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. **/ int rarch_main_iterate(void) { unsigned i; retro_input_t trigger_input, old_input; event_cmd_state_t cmd = {0}; int ret = 0; static retro_input_t last_input = 0; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); runloop_t *runloop = rarch_main_get_ptr(); retro_input_t input = input_keys_pressed(driver, settings, global); rarch_system_info_t *system = rarch_system_info_get_ptr(); old_input = last_input; last_input = input; if (driver->flushing_input) driver->flushing_input = (input) ? input_flush(runloop, &input) : false; trigger_input = input & ~old_input; rarch_main_cmd_get_state(&cmd, input, old_input, trigger_input); if (time_to_exit(driver, global, runloop, &cmd)) return rarch_main_iterate_quit(settings, global); if (system->frame_time.callback) rarch_update_frame_time(driver, settings, runloop); do_pre_state_checks(settings, global, runloop, &cmd); #ifdef HAVE_OVERLAY rarch_main_iterate_linefeed_overlay(driver, settings); #endif #ifdef HAVE_MENU if (menu_driver_alive()) { menu_handle_t *menu = menu_driver_get_ptr(); if (menu) if (menu_iterate(input, old_input, trigger_input) == -1) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); if (!input && settings->menu.pause_libretro) ret = 1; goto success; } #endif if (global->exec) { global->exec = false; return rarch_main_iterate_quit(settings, global); } if (do_state_checks(driver, settings, global, runloop, &cmd)) { /* RetroArch has been paused */ driver->retro_ctx.poll_cb(); rarch_sleep(10); return 1; } #if defined(HAVE_THREADS) lock_autosave(); #endif #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_pre_frame((netplay_t*)driver->netplay_data); #endif if (global->bsv.movie) bsv_movie_set_frame_start(global->bsv.movie); if (system->camera_callback.caps) driver_camera_poll(); /* Update binds for analog dpad modes. */ for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_push_analog_dpad(settings->input.binds[i], settings->input.analog_dpad_mode[i]); input_push_analog_dpad(settings->input.autoconf_binds[i], settings->input.analog_dpad_mode[i]); } if ((settings->video.frame_delay > 0) && !driver->nonblock_state) rarch_sleep(settings->video.frame_delay); /* Run libretro for one frame. */ pretro_run(); for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_pop_analog_dpad(settings->input.binds[i]); input_pop_analog_dpad(settings->input.autoconf_binds[i]); } if (global->bsv.movie) bsv_movie_set_frame_end(global->bsv.movie); #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_post_frame((netplay_t*)driver->netplay_data); #endif #if defined(HAVE_THREADS) unlock_autosave(); #endif success: if (settings->fastforward_ratio_throttle_enable) rarch_limit_frame_time(settings, runloop); return ret; }
/** * rarch_main_iterate: * * Run Libretro core in RetroArch for one frame. * * Returns: 0 on success, 1 if we have to wait until button input in order * to wake up the loop, -1 if we forcibly quit out of the RetroArch iteration loop. **/ int rarch_main_iterate(unsigned *sleep_ms) { unsigned i; retro_input_t trigger_input; event_cmd_state_t cmd; bool do_quit = false; static retro_input_t last_input = 0; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); retro_input_t input = input_keys_pressed(driver, settings, global); rarch_system_info_t *system = rarch_system_info_get_ptr(); retro_input_t old_input = last_input; last_input = input; if (driver->flushing_input) { driver->flushing_input = false; if (input) { input = 0; /* If core was paused before entering menu, evoke * pause toggle to wake it up. */ if (main_is_paused) BIT64_SET(input, RARCH_PAUSE_TOGGLE); driver->flushing_input = true; } } trigger_input = input & ~old_input; rarch_main_cmd_get_state(driver, settings, &cmd, input, old_input, trigger_input); if (time_to_exit(driver, global, system, &cmd)) do_quit = true; if (system->frame_time.callback) rarch_update_frame_time(driver, settings->slowmotion_ratio, system); do_pre_state_checks(settings, global, &cmd); #ifdef HAVE_OVERLAY rarch_main_iterate_linefeed_overlay(driver, settings); #endif if (global->exec) { global->exec = false; do_quit = true; } if (do_quit) { /* Quits out of RetroArch main loop. * On special case, loads dummy core * instead of exiting RetroArch completely. * Aborts core shutdown if invoked. */ if (global->core_shutdown_initiated && settings->load_dummy_on_core_shutdown) { if (!event_command(EVENT_CMD_PREPARE_DUMMY)) return -1; system->shutdown = false; global->core_shutdown_initiated = false; return 0; } return -1; } #ifdef HAVE_MENU if (menu_driver_alive()) { menu_handle_t *menu = menu_driver_get_ptr(); if (menu) if (menu_iterate(true, menu_input_frame(input, trigger_input)) == -1) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); if (!input && settings->menu.pause_libretro) return 1; return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms); } #endif if (do_state_checks(driver, settings, global, &cmd)) { /* RetroArch has been paused. */ driver->retro_ctx.poll_cb(); *sleep_ms = 10; return 1; } #if defined(HAVE_THREADS) lock_autosave(); #endif #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_pre_frame((netplay_t*)driver->netplay_data); #endif if (global->bsv.movie) bsv_movie_set_frame_start(global->bsv.movie); if (system->camera_callback.caps) driver_camera_poll(); /* Update binds for analog dpad modes. */ for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_push_analog_dpad(settings->input.binds[i], settings->input.analog_dpad_mode[i]); input_push_analog_dpad(settings->input.autoconf_binds[i], settings->input.analog_dpad_mode[i]); } if ((settings->video.frame_delay > 0) && !driver->nonblock_state) rarch_sleep(settings->video.frame_delay); /* Run libretro for one frame. */ pretro_run(); for (i = 0; i < settings->input.max_users; i++) { if (!settings->input.analog_dpad_mode[i]) continue; input_pop_analog_dpad(settings->input.binds[i]); input_pop_analog_dpad(settings->input.autoconf_binds[i]); } if (global->bsv.movie) bsv_movie_set_frame_end(global->bsv.movie); #ifdef HAVE_NETPLAY if (driver->netplay_data) netplay_post_frame((netplay_t*)driver->netplay_data); #endif #if defined(HAVE_THREADS) unlock_autosave(); #endif return rarch_limit_frame_time(settings->fastforward_ratio, sleep_ms); }
int rarch_main_iterate(void) { unsigned i; retro_input_t trigger_input; int ret = 0; static retro_input_t last_input = 0; retro_input_t old_input = last_input; retro_input_t input = input_keys_pressed(); last_input = input; if (driver.flushing_input) driver.flushing_input = (input) ? input_flush(&input) : false; trigger_input = input & ~old_input; if (time_to_exit(input)) return -1; if (g_extern.system.frame_time.callback) update_frame_time(); #ifdef HAVE_MENU if (check_enter_menu_func(trigger_input) || (g_extern.libretro_dummy)) do_state_check_menu_toggle(); if (g_extern.is_menu) { if (menu_iterate(input, old_input, trigger_input) == -1) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); if (!input && g_settings.menu.pause_libretro) ret = 1; goto success; } #endif if (g_extern.exec) { g_extern.exec = false; return -1; } if (do_state_checks(input, old_input, trigger_input)) { /* RetroArch has been paused */ driver.retro_ctx.poll_cb(); rarch_sleep(10); return 1; } #if defined(HAVE_THREADS) lock_autosave(); #endif #ifdef HAVE_NETPLAY if (driver.netplay_data) netplay_pre_frame((netplay_t*)driver.netplay_data); #endif if (g_extern.bsv.movie) bsv_movie_set_frame_start(g_extern.bsv.movie); if (g_extern.system.camera_callback.caps) driver_camera_poll(); /* Update binds for analog dpad modes. */ for (i = 0; i < MAX_PLAYERS; i++) { if (!g_settings.input.analog_dpad_mode[i]) continue; input_push_analog_dpad(g_settings.input.binds[i], g_settings.input.analog_dpad_mode[i]); input_push_analog_dpad(g_settings.input.autoconf_binds[i], g_settings.input.analog_dpad_mode[i]); } if ((g_settings.video.frame_delay > 0) && !driver.nonblock_state) rarch_sleep(g_settings.video.frame_delay); /* Run libretro for one frame. */ pretro_run(); for (i = 0; i < MAX_PLAYERS; i++) { if (!g_settings.input.analog_dpad_mode[i]) continue; input_pop_analog_dpad(g_settings.input.binds[i]); input_pop_analog_dpad(g_settings.input.autoconf_binds[i]); } if (g_extern.bsv.movie) bsv_movie_set_frame_end(g_extern.bsv.movie); #ifdef HAVE_NETPLAY if (driver.netplay_data) netplay_post_frame((netplay_t*)driver.netplay_data); #endif #if defined(HAVE_THREADS) unlock_autosave(); #endif success: if (g_settings.fastforward_ratio_throttle_enable) limit_frame_time(); return ret; }