mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
Savestate tweaks (#999)
* move savestate processing * fix stack overflow * more * more
This commit is contained in:
@@ -703,8 +703,11 @@ void rdp_check_framebuffers(uint32_t address, uint32_t length) {
|
||||
size_t rdp_state_size() { return sizeof(RDP_DEVICE); }
|
||||
|
||||
void rdp_save_state(uint8_t *state, bool rewind) {
|
||||
if (!rewind) // speed hack for rewind
|
||||
processor->wait_for_timeline(processor->signal_timeline());
|
||||
if (!rewind) { // speed hack for rewind
|
||||
processor->idle();
|
||||
rdram_dirty.assign(gfx_info.RDRAM_SIZE >> 3, false);
|
||||
sync_signal = 0;
|
||||
}
|
||||
memcpy(state, &rdp_device, sizeof(RDP_DEVICE));
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -229,6 +229,7 @@ pub struct Device {
|
||||
#[serde(skip)]
|
||||
pub ui: ui::Ui,
|
||||
pub byte_swap: usize,
|
||||
pub frame_counter: u64,
|
||||
pub savestate: savestates::Savestate,
|
||||
pub cpu: cpu::Cpu,
|
||||
pub pif: pif::Pif,
|
||||
@@ -290,6 +291,7 @@ impl Device {
|
||||
ui::Ui::default()
|
||||
},
|
||||
byte_swap,
|
||||
frame_counter: 0,
|
||||
savestate: savestates::Savestate {
|
||||
save_state: false,
|
||||
load_state: false,
|
||||
@@ -529,7 +531,6 @@ impl Device {
|
||||
count_per_scanline: 0,
|
||||
enable_speed_limiter: true,
|
||||
next_pace_deadline: None,
|
||||
vi_counter: 0,
|
||||
min_wait_time: std::time::Duration::from_secs(1),
|
||||
frame_time: 0.0,
|
||||
elapsed_time: 0.0,
|
||||
|
||||
@@ -58,12 +58,12 @@ pub fn process(device: &mut device::Device, channel: usize) {
|
||||
let offset = device.pif.channels[channel].rx_buf.unwrap();
|
||||
let input = if let Some(netplay) = &mut device.netplay {
|
||||
if netplay.player_number as usize == channel {
|
||||
let local_input = ui::input::get(&mut device.ui, 0, device.vi.vi_counter);
|
||||
let local_input = ui::input::get(&mut device.ui, 0, device.frame_counter);
|
||||
netplay::send_input(netplay, local_input);
|
||||
}
|
||||
netplay::get_input(device, channel)
|
||||
} else {
|
||||
ui::input::get(&mut device.ui, channel, device.vi.vi_counter)
|
||||
ui::input::get(&mut device.ui, channel, device.frame_counter)
|
||||
};
|
||||
|
||||
device.pif.ram[offset..offset + 4].copy_from_slice(&input.data.to_ne_bytes());
|
||||
|
||||
+1
-15
@@ -120,21 +120,7 @@ fn run_rdp(device: &mut device::Device) {
|
||||
device.rdp.regs_dpc[DPC_PIPEBUSY_REG] = 0xFFFFFF;
|
||||
|
||||
if timer != 0 {
|
||||
if device.savestate.save_state || device.savestate.save_rewind {
|
||||
// Right after full sync, good time for save state
|
||||
let rewind = device.savestate.save_rewind && !device.savestate.save_state;
|
||||
if rewind {
|
||||
device.savestate.save_rewind = false;
|
||||
}
|
||||
device.savestate.save_state = false;
|
||||
savestates::create_savestate(device, rewind);
|
||||
} else if device.savestate.load_state || device.savestate.load_rewind {
|
||||
// Right after full sync, good time for save state
|
||||
device.savestate.load_state = false;
|
||||
let rewind = device.savestate.load_rewind;
|
||||
device.savestate.load_rewind = false;
|
||||
savestates::load_savestate(device, rewind);
|
||||
}
|
||||
savestates::process_savestates(device);
|
||||
device::events::create_event(device, device::events::EVENT_TYPE_DP, timer)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -26,7 +26,6 @@ pub struct Vi {
|
||||
pub next_pace_deadline: Option<std::time::Instant>,
|
||||
pub count_per_scanline: u64,
|
||||
pub enable_speed_limiter: bool,
|
||||
pub vi_counter: u64,
|
||||
pub min_wait_time: std::time::Duration,
|
||||
pub frame_time: f64,
|
||||
pub elapsed_time: f64,
|
||||
@@ -152,14 +151,14 @@ pub fn vertical_interrupt_event(device: &mut device::Device) {
|
||||
reset_pace_deadline(device);
|
||||
}
|
||||
|
||||
if device.vi.vi_counter.is_multiple_of(device.vi.limit_freq) && device.vi.enable_speed_limiter {
|
||||
if device.frame_counter.is_multiple_of(device.vi.limit_freq) && device.vi.enable_speed_limiter {
|
||||
speed_limiter(device);
|
||||
}
|
||||
|
||||
unsafe { sdl3_sys::events::SDL_PumpEvents() };
|
||||
|
||||
ui::video::update_screen();
|
||||
device.vi.vi_counter += 1;
|
||||
device.frame_counter += 1;
|
||||
|
||||
if device.netplay.is_none() && paused {
|
||||
if retroachievements::get_hardcore() {
|
||||
|
||||
+20
-4
@@ -94,7 +94,23 @@ static DEVICE_CLONE: std::sync::LazyLock<std::sync::Mutex<device::Device>> =
|
||||
static SAVES_CLONE: std::sync::LazyLock<std::sync::Mutex<ui::storage::Saves>> =
|
||||
std::sync::LazyLock::new(|| std::sync::Mutex::new(ui::storage::Saves::default()));
|
||||
|
||||
pub fn create_savestate(device: &mut device::Device, rewind: bool) {
|
||||
pub fn process_savestates(device: &mut device::Device) {
|
||||
if device.savestate.save_state || device.savestate.save_rewind {
|
||||
let rewind = device.savestate.save_rewind && !device.savestate.save_state;
|
||||
if rewind {
|
||||
device.savestate.save_rewind = false;
|
||||
}
|
||||
device.savestate.save_state = false;
|
||||
create_savestate(device, rewind);
|
||||
} else if device.savestate.load_state || device.savestate.load_rewind {
|
||||
device.savestate.load_state = false;
|
||||
let rewind = device.savestate.load_rewind;
|
||||
device.savestate.load_rewind = false;
|
||||
load_savestate(device, rewind);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_savestate(device: &mut device::Device, rewind: bool) {
|
||||
let mut rdp_state: Vec<u8> = vec![0; ui::video::state_size()];
|
||||
ui::video::save_state(rdp_state.as_mut_ptr(), rewind);
|
||||
|
||||
@@ -175,7 +191,7 @@ pub fn create_savestate(device: &mut device::Device, rewind: bool) {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn load_savestate(device: &mut device::Device, rewind: bool) {
|
||||
fn load_savestate(device: &mut device::Device, rewind: bool) {
|
||||
if retroachievements::get_hardcore() {
|
||||
ui::video::onscreen_message(
|
||||
"Cannot load savestate in RA hardcore mode",
|
||||
@@ -196,11 +212,11 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool) {
|
||||
&& let Ok(saves_data) = ui::storage::decompress_file(savestate, "saves")
|
||||
&& let Ok(rdp_state) = ui::storage::decompress_file(savestate, "rdp_state")
|
||||
&& let Ok(ra_state) = ui::storage::decompress_file(savestate, "ra_state")
|
||||
&& let Ok(state) = postcard::from_bytes::<device::Device>(&device_data)
|
||||
&& let Ok(state) = postcard::from_bytes::<Box<device::Device>>(&device_data)
|
||||
&& let Ok(saves) = postcard::from_bytes(&saves_data)
|
||||
{
|
||||
Some(SavestateData {
|
||||
device: state,
|
||||
device: *state,
|
||||
saves,
|
||||
rdp_state,
|
||||
ra_state,
|
||||
|
||||
Reference in New Issue
Block a user