ferretro/ferretro_components/src/provided/stdlib/saves.rs

48 lines
1.5 KiB
Rust

use std::error::Error;
use std::fs::File;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use crate::prelude::{LibretroWrapper, RetroCallbacks, RetroComponent};
use ferretro_base::retro::ffi::MEMORY_SAVE_RAM;
#[derive(Default)]
pub struct LocalFileSaveComponent {
rom_path: PathBuf,
initial_sram: Vec<u8>,
}
impl LocalFileSaveComponent {
fn save_path(&self) -> PathBuf {
self.rom_path.with_extension("sav")
}
}
impl RetroComponent for LocalFileSaveComponent {
fn post_load_game(&mut self, retro: &mut LibretroWrapper, rom: &Path) -> Result<(), Box<dyn Error + Send + Sync>> {
self.rom_path = rom.to_path_buf();
let save = self.save_path();
if save.is_file() {
File::open(&save)?.read(retro.mut_memory(MEMORY_SAVE_RAM))?;
}
self.initial_sram = retro.get_memory(MEMORY_SAVE_RAM).to_vec();
Ok(())
}
fn pre_drop(&mut self, retro: &mut LibretroWrapper) {
let final_sram = retro.get_memory(MEMORY_SAVE_RAM);
if &self.initial_sram != final_sram {
let save = self.save_path();
match File::create(&save) {
Ok(mut f) => if let Err(e) = f.write(final_sram) {
eprintln!("Couldn't write save to {:?}: {:?}", save, e);
}
Err(e) => {
eprintln!("Couldn't (over)write {:?}: {:?}", save, e);
}
}
}
}
}
impl RetroCallbacks for LocalFileSaveComponent {}