diff --git a/examples/ffmpeg_recorder.rs b/examples/ffmpeg_recorder.rs index c63057a..72474a3 100644 --- a/examples/ffmpeg_recorder.rs +++ b/examples/ffmpeg_recorder.rs @@ -380,6 +380,17 @@ static bool ffmpeg_init_config(struct ff_config_param *params, self.receive_and_write_packets(EncoderToWriteFrom::Audio); self.octx.write_trailer().unwrap(); } + + pub fn unserialize(&mut self, state: impl AsRef) -> Fallible<()> { + let path = state.as_ref(); + let mut v = Vec::new(); + if let Ok(mut f) = std::fs::File::open(path) { + if f.read_to_end(&mut v).is_ok(){ + return self.retro.unserialize(v.as_ref()); + } + } + Err(failure::err_msg("Couldn't read file to unserialize")) + } } impl retro::wrapper::Handler for MyEmulator { @@ -511,6 +522,9 @@ struct Opt { /// Recorded video to write. #[structopt(short, long, parse(from_os_str))] video: PathBuf, + /// Save state to load at startup. + #[structopt(long, parse(from_os_str))] + state: Option, /// System directory, often containing BIOS files #[structopt(short, long, parse(from_os_str))] system: Option, @@ -535,6 +549,10 @@ fn main() -> Fallible<()> { emu.frame_properties_locked = true; + if let Some(state) = opt.state { + emu.unserialize(state).unwrap(); + } + //for frame in 0..60*10 { for frame in 0..800 { eprintln!("🖼️ frame: {}", frame); diff --git a/src/retro/loading.rs b/src/retro/loading.rs index 552e458..a0da355 100644 --- a/src/retro/loading.rs +++ b/src/retro/loading.rs @@ -142,6 +142,12 @@ impl LibretroApi { } } pub fn unserialize(&self, data: &[u8]) -> Fallible<()> { + // validate size of the data + let size: usize = unsafe { (&self.core_api.retro_serialize_size)() }; + if data.len() != size { + return Err(failure::err_msg(format!("Size of data {} doesn't match this core's expected size {}", data.len(), size))) + } + if unsafe { (&self.core_api.retro_unserialize)(data.as_ptr() as *const c_void, data.len()) } { Ok(()) } else {