diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs index d0b54912ad7ac87596644530d3cec9970f6d770f..2fcab56bae92774dd8288a273acccc39eef9baf7 100644 --- a/frontends/sdl/src/main.rs +++ b/frontends/sdl/src/main.rs @@ -13,6 +13,7 @@ use boytacean::{ ppu::{PaletteInfo, PpuMode}, rom::Cartridge, serial::{NullDevice, SerialDevice}, + util::replace_ext, }; use chrono::Utc; use clap::Parser; @@ -202,10 +203,15 @@ impl Emulator { } pub fn load_rom(&mut self, path: Option<&str>) { - let path_res = path.unwrap_or(&self.rom_path); + let rom_path: &str = path.unwrap_or(&self.rom_path); + let ram_path = replace_ext(rom_path, "sav").unwrap_or("".to_string()); let rom = self.system.load_rom_file( - path_res, - Some("C:/repo.other/boytacean/res/roms.prop/super_mario_2.sav"), + rom_path, + if Path::new(&ram_path).exists() { + Some(&ram_path) + } else { + None + }, ); println!( "========= Cartridge =========\n{}\n=============================", @@ -216,7 +222,7 @@ impl Emulator { .set_title(format!("{} [{}]", self.title, rom.title()).as_str()) .unwrap(); } - self.rom_path = String::from(path_res); + self.rom_path = String::from(rom_path); } pub fn reset(&mut self) { diff --git a/src/util.rs b/src/util.rs index 96776eecc5b692c096fae2dabd603f119a988465..37393a92af50fd4beca022bebed6167058426143 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, fs::File, io::Read, rc::Rc}; +use std::{cell::RefCell, fs::File, io::Read, path::Path, rc::Rc}; pub type SharedMut<T> = Rc<RefCell<T>>; @@ -11,3 +11,53 @@ pub fn read_file(path: &str) -> Vec<u8> { file.read_to_end(&mut data).unwrap(); data } + +/// Replaces the extension in the given path with the provided extension. +/// This function allows for simple associated file discovery. +pub fn replace_ext(path: &str, new_extension: &str) -> Option<String> { + let file_path = Path::new(path); + let parent_dir = file_path.parent()?; + let file_stem = file_path.file_stem()?; + let file_extension = file_path.extension()?; + if file_stem == file_extension { + return None; + } + let new_file_name = format!("{}.{}", file_stem.to_str()?, new_extension); + let new_file_path = parent_dir.join(new_file_name); + Some(String::from(new_file_path.to_str()?)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_change_extension() { + let new_path = replace_ext("/path/to/file.txt", "dat").unwrap(); + assert_eq!( + new_path, + Path::new("/path/to").join("file.dat").to_str().unwrap() + ); + + let new_path = replace_ext("/path/to/file.with.multiple.dots.txt", "dat").unwrap(); + assert_eq!( + new_path, + Path::new("/path/to") + .join("file.with.multiple.dots.dat") + .to_str() + .unwrap() + ); + + let new_path = replace_ext("/path/to/file.without.extension", "dat").unwrap(); + assert_eq!( + new_path, + Path::new("/path/to") + .join("file.without.dat") + .to_str() + .unwrap() + ); + + let new_path = replace_ext("/path/to/directory/", "dat"); + assert_eq!(new_path, None); + } +}