diff --git a/src/bin/example.rs b/src/bin/example.rs index a99d840..6486f63 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -19,11 +19,13 @@ use sdl2::controller::{GameController, Button, Axis}; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::rect::Rect; -use sdl2::render::{TextureCreator, WindowCanvas}; -use sdl2::video::WindowContext; +use sdl2::render::WindowCanvas; struct MyEmulator { retro: retro::wrapper::LibretroWrapper, + core_path: PathBuf, + sys_path: Option, + sys_info: SystemInfo, av_info: SystemAvInfo, @@ -32,7 +34,6 @@ struct MyEmulator { // video bits canvas: WindowCanvas, pixel_format: sdl2::pixels::PixelFormatEnum, - texture_creator: TextureCreator, // audio bits audio_buffer: Vec, @@ -46,8 +47,9 @@ struct MyEmulator { } impl MyEmulator { - pub fn with_core(core: impl AsRef) -> Pin> { - let lib = libloading::Library::new(core.as_ref()).unwrap(); + pub fn new(core_path: impl AsRef, sys_path: &Option>) -> Pin> { + let core_path = PathBuf::from(core_path.as_ref()); + let lib = libloading::Library::new(&core_path).unwrap(); let raw_retro = retro::loading::LibretroApi::from_library(lib).unwrap(); let retro = retro::wrapper::LibretroWrapper::from(raw_retro); @@ -72,18 +74,15 @@ impl MyEmulator { let sdl_context = sdl2::init().unwrap(); - let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height); - let window = sdl_context .video() .unwrap() - .window(title.as_str(), width, height) + .window(title.as_str(), av_info.geometry.base_width, av_info.geometry.base_height) .opengl() .build() .unwrap(); let canvas = window.into_canvas().build().unwrap(); - let texture_creator = canvas.texture_creator(); let (audio_sender, audio_receiver) = crossbeam_channel::bounded(2); @@ -115,18 +114,19 @@ impl MyEmulator { let emu = MyEmulator { retro, + core_path, av_info, sys_info, sdl_context, canvas, pixel_format, - texture_creator, audio_buffer: Default::default(), audio_spec: audio_spec.unwrap(), audio_device, audio_sender, gamepad_subsys, gamepads, + sys_path: sys_path.as_ref().map(|p| p.as_ref().to_path_buf()) }; let mut pin_emu = Box::pin(emu); retro::wrapper::set_handler(pin_emu.as_mut()); @@ -198,7 +198,8 @@ impl retro::wrapper::Handler for MyEmulator { let rect = Rect::new(0, 0, width, height); if let Ok(mut tex) = - self.texture_creator + self.canvas + .texture_creator() .create_texture_static(self.pixel_format, width, height) { if tex.update(rect, data, pitch as usize).is_ok() { @@ -248,6 +249,10 @@ impl retro::wrapper::Handler for MyEmulator { fn get_can_dupe(&mut self) -> Option { Some(true) } + fn get_system_directory(&mut self) -> Option { + self.sys_path.clone() + } + fn set_pixel_format(&mut self, pix_fmt: retro::ffi::PixelFormat) -> bool { self.pixel_format = match pix_fmt { retro::ffi::PixelFormat::ARGB1555 => sdl2::pixels::PixelFormatEnum::RGB555, @@ -257,18 +262,22 @@ impl retro::wrapper::Handler for MyEmulator { true } + fn get_libretro_path(&mut self) -> Option { + Some(self.core_path.clone()) + } + + fn get_save_directory(&mut self) -> Option { + Some(std::env::temp_dir()) + } + fn set_system_av_info(&mut self, av_info: SystemAvInfo) -> bool { - let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height); - let _ = self.canvas.window_mut().set_size(width, height); - let _ = self.canvas.set_logical_size(width, height); + self.set_geometry(av_info.geometry.clone()); self.av_info = av_info; true } - fn set_geometry(&mut self, geom: GameGeometry) -> bool { - let (width, height) = (geom.base_width, geom.base_height); - let _ = self.canvas.window_mut().set_size(width, height); - let _ = self.canvas.set_logical_size(width, height); + let _ = self.canvas.window_mut().set_size(geom.base_width, geom.base_height); + let _ = self.canvas.set_logical_size(geom.base_width, geom.base_height); self.av_info.geometry = geom; true } @@ -278,7 +287,6 @@ impl retro::wrapper::Handler for MyEmulator { } } - struct MySdlAudio { audio_spec: AudioSpec, audio_receiver: crossbeam_channel::Receiver>, @@ -298,7 +306,7 @@ impl AudioCallback for MySdlAudio { pub fn main() -> failure::Fallible<()> { let opt: Opt = Opt::from_args(); - let mut emu = MyEmulator::with_core(&opt.core); + let mut emu = MyEmulator::new(&opt.core, &opt.system); emu.load_game(&opt.rom); emu.run(); @@ -310,9 +318,12 @@ struct Opt { /// Core module to use. #[structopt(short, long, parse(from_os_str))] core: PathBuf, - /// Rom to load using the core. + /// ROM to load using the core. #[structopt(short, long, parse(from_os_str))] rom: PathBuf, + /// System directory, often containing BIOS files + #[structopt(short, long, parse(from_os_str))] + system: Option, } fn button_map(retro_button: &JoypadButton) -> Option