void state_manager_push_where(state_manager_t *state, void **data) { /* We need to ensure we have an uncompressed copy of the last * pushed state, or we could end up applying a 'patch' to wrong * savestate, and that'd blow up rather quickly. */ if (!state->thisblock_valid) { const void *ignored; if (state_manager_pop(state, &ignored)) { state->thisblock_valid = true; state->entries++; } } *data = state->nextblock; }
/** * check_rewind: * @pressed : was rewind key pressed or held? * * Checks if rewind toggle/hold was being pressed and/or held. **/ static void check_rewind(settings_t *settings, global_t *global, bool pressed) { static bool first = true; if (state_manager_frame_is_reversed()) { audio_driver_frame_is_reverse(); state_manager_set_frame_is_reversed(false); } if (first) { first = false; return; } if (!global->rewind.state) return; if (pressed) { const void *buf = NULL; if (state_manager_pop(global->rewind.state, &buf)) { state_manager_set_frame_is_reversed(true); audio_driver_setup_rewind(); rarch_main_msg_queue_push_new(MSG_REWINDING, 0, main_is_paused ? 1 : 30, true); core.retro_unserialize(buf, global->rewind.size); if (global->bsv.movie) bsv_movie_frame_rewind(global->bsv.movie); } else rarch_main_msg_queue_push_new(MSG_REWIND_REACHED_END, 0, 30, true); } else { static unsigned cnt = 0; cnt = (cnt + 1) % (settings->rewind_granularity ? settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */ if ((cnt == 0) || global->bsv.movie) { static struct retro_perf_counter rewind_serialize = {0}; void *state = NULL; state_manager_push_where(global->rewind.state, &state); rarch_perf_init(&rewind_serialize, "rewind_serialize"); retro_perf_start(&rewind_serialize); core.retro_serialize(state, global->rewind.size); retro_perf_stop(&rewind_serialize); state_manager_push_do(global->rewind.state); } } retro_set_rewind_callbacks(); }
static void check_rewind(bool pressed) { static bool first = true; if (g_extern.frame_is_reverse) { /* We just rewound. Flush rewind audio buffer. */ retro_flush_audio(g_extern.audio_data.rewind_buf + g_extern.audio_data.rewind_ptr, g_extern.audio_data.rewind_size - g_extern.audio_data.rewind_ptr); g_extern.frame_is_reverse = false; } if (first) { first = false; return; } if (!g_extern.state_manager) return; if (pressed) { const void *buf = NULL; msg_queue_clear(g_extern.msg_queue); if (state_manager_pop(g_extern.state_manager, &buf)) { g_extern.frame_is_reverse = true; setup_rewind_audio(); msg_queue_push(g_extern.msg_queue, RETRO_MSG_REWINDING, 0, g_extern.is_paused ? 1 : 30); pretro_unserialize(buf, g_extern.state_size); if (g_extern.bsv.movie) bsv_movie_frame_rewind(g_extern.bsv.movie); } else msg_queue_push(g_extern.msg_queue, RETRO_MSG_REWIND_REACHED_END, 0, 30); } else { static unsigned cnt = 0; cnt = (cnt + 1) % (g_settings.rewind_granularity ? g_settings.rewind_granularity : 1); /* Avoid possible SIGFPE. */ if ((cnt == 0) || g_extern.bsv.movie) { void *state = NULL; state_manager_push_where(g_extern.state_manager, &state); RARCH_PERFORMANCE_INIT(rewind_serialize); RARCH_PERFORMANCE_START(rewind_serialize); pretro_serialize(state, g_extern.state_size); RARCH_PERFORMANCE_STOP(rewind_serialize); state_manager_push_do(g_extern.state_manager); } } retro_set_rewind_callbacks(); }
/** * check_rewind: * @pressed : was rewind key pressed or held? * * Checks if rewind toggle/hold was being pressed and/or held. **/ static void check_rewind(settings_t *settings, global_t *global, runloop_t *runloop, bool pressed) { static bool first = true; if (global->rewind.frame_is_reverse) { audio_driver_frame_is_reverse(); global->rewind.frame_is_reverse = false; } if (first) { first = false; return; } if (!global->rewind.state) return; if (pressed) { const void *buf = NULL; if (state_manager_pop(global->rewind.state, &buf)) { global->rewind.frame_is_reverse = true; audio_driver_setup_rewind(); rarch_main_msg_queue_push_new(MSG_REWINDING, 0, runloop->is_paused ? 1 : 30, true); pretro_unserialize(buf, global->rewind.size); if (global->bsv.movie) bsv_movie_frame_rewind(global->bsv.movie); } else rarch_main_msg_queue_push_new(MSG_REWIND_REACHED_END, 0, 30, true); } else { static unsigned cnt = 0; cnt = (cnt + 1) % (settings->rewind_granularity ? settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */ if ((cnt == 0) || global->bsv.movie) { void *state = NULL; state_manager_push_where(global->rewind.state, &state); RARCH_PERFORMANCE_INIT(rewind_serialize); RARCH_PERFORMANCE_START(rewind_serialize); pretro_serialize(state, global->rewind.size); RARCH_PERFORMANCE_STOP(rewind_serialize); state_manager_push_do(global->rewind.state); } } retro_set_rewind_callbacks(); }
/** * check_rewind: * @pressed : was rewind key pressed or held? * * Checks if rewind toggle/hold was being pressed and/or held. **/ void state_manager_check_rewind(bool pressed) { static bool first = true; settings_t *settings = config_get_ptr(); if (state_manager_frame_is_reversed()) { audio_driver_frame_is_reverse(); state_manager_set_frame_is_reversed(false); } if (first) { first = false; return; } if (!rewind_state.state) return; if (pressed) { const void *buf = NULL; if (state_manager_pop(rewind_state.state, &buf)) { retro_ctx_serialize_info_t serial_info; state_manager_set_frame_is_reversed(true); audio_driver_setup_rewind(); runloop_msg_queue_push( msg_hash_to_str(MSG_REWINDING), 0, runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) ? 1 : 30, true); serial_info.data_const = buf; serial_info.size = rewind_state.size; core_unserialize(&serial_info); if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) bsv_movie_ctl(BSV_MOVIE_CTL_FRAME_REWIND, NULL); } else runloop_msg_queue_push( msg_hash_to_str(MSG_REWIND_REACHED_END), 0, 30, true); } else { static unsigned cnt = 0; cnt = (cnt + 1) % (settings->rewind_granularity ? settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */ if ((cnt == 0) || bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) { retro_ctx_serialize_info_t serial_info; static struct retro_perf_counter rewind_serialize = {0}; void *state = NULL; state_manager_push_where(rewind_state.state, &state); performance_counter_init(&rewind_serialize, "rewind_serialize"); performance_counter_start(&rewind_serialize); serial_info.data = state; serial_info.size = rewind_state.size; core_serialize(&serial_info); performance_counter_stop(&rewind_serialize); state_manager_push_do(rewind_state.state); } } core_set_rewind_callbacks(); }