diff --git a/ferretro_components/examples/multifunction_emulator.rs b/ferretro_components/examples/multifunction_emulator.rs index e14375b..46bdd2e 100644 --- a/ferretro_components/examples/multifunction_emulator.rs +++ b/ferretro_components/examples/multifunction_emulator.rs @@ -41,6 +41,8 @@ pub fn main() { let mut sdl_context = sdl2::init().unwrap(); + emu.register_component(StderrLogComponent { prefix: "{log} ".to_string() }); + //let sdl2_canvas = SimpleSdl2CanvasComponent::new(&mut sdl_context, emu.libretro_core()); let sdl2_canvas = SimpleSdl2OpenglComponent::new(&mut sdl_context, emu.libretro_core()).unwrap(); emu.register_component(sdl2_canvas); @@ -53,7 +55,6 @@ pub fn main() { let sleep_fps = SleepFramerateLimitComponent::new(emu.libretro_core()); emu.register_component(sleep_fps); - emu.register_component(StderrLogComponent::default()); emu.register_component(PathBufComponent { sys_path: opt.system.clone(), libretro_path: Some(opt.core.to_path_buf()), diff --git a/ferretro_components/src/lib.rs b/ferretro_components/src/lib.rs index 29c76cd..0fc18aa 100644 --- a/ferretro_components/src/lib.rs +++ b/ferretro_components/src/lib.rs @@ -6,5 +6,5 @@ pub mod prelude { pub use ferretro_base::retro::constants::*; pub use ferretro_base::retro::wrapped_types::*; pub use ferretro_base::retro::wrapper::{RetroCallbacks, LibretroWrapper, LibretroWrapperAccess}; - pub use ferretro_base::retro::ffi::{PixelFormat, GameGeometry, HwContextResetFn, HwRenderCallback, SystemAvInfo, SystemInfo}; + pub use ferretro_base::retro::ffi::{PixelFormat, GameGeometry, HwContextResetFn, HwRenderCallback, SystemAvInfo, SystemInfo, MemoryMap}; } diff --git a/ferretro_components/src/provided/sdl2/canvas.rs b/ferretro_components/src/provided/sdl2/canvas.rs index ae12a3f..f69e9d4 100644 --- a/ferretro_components/src/provided/sdl2/canvas.rs +++ b/ferretro_components/src/provided/sdl2/canvas.rs @@ -16,7 +16,7 @@ impl SimpleSdl2CanvasComponent { pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Self { let sys_info = retro.get_system_info(); let title = format!( - "{} - ferretro", + "{} - ferretro SDL", unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy() ); diff --git a/ferretro_components/src/provided/sdl2/opengl.rs b/ferretro_components/src/provided/sdl2/opengl.rs index ab381dd..75c3fbe 100644 --- a/ferretro_components/src/provided/sdl2/opengl.rs +++ b/ferretro_components/src/provided/sdl2/opengl.rs @@ -4,7 +4,7 @@ use crate::prelude::*; use std::ffi::CStr; use std::os::raw::c_uint; -use sdl2::Sdl; +use sdl2::{Sdl, VideoSubsystem}; use sdl2::video::{GLContext, Window}; pub struct SimpleSdl2OpenglComponent { @@ -20,7 +20,7 @@ impl SimpleSdl2OpenglComponent { pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Result> { let sys_info = retro.get_system_info(); let title = format!( - "{} - ferretro", + "{} - ferretro SDL GL", unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy() ); @@ -36,15 +36,7 @@ impl SimpleSdl2OpenglComponent { // http://forums.libsdl.org/viewtopic.php?p=43353 // likely to remain `0` on any platform that isn't iOS, but we'll do it anyhow let gl_context = window.gl_create_context()?; - let mut window_fbo: c_uint = 0; - unsafe { - const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6; - #[allow(non_snake_case)] - let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = std::mem::transmute( - video.gl_get_proc_address("glGetIntegerv") - ); - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut window_fbo); - } + let window_fbo = Self::current_framebuffer_binding(&video); Ok(SimpleSdl2OpenglComponent { window, @@ -55,6 +47,28 @@ impl SimpleSdl2OpenglComponent { hw_context_destroy_fn: None, }) } + + fn current_framebuffer_binding(video: &VideoSubsystem) -> c_uint { + let mut fbo: c_uint = 0; + unsafe { + const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6; + #[allow(non_snake_case)] + let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = std::mem::transmute( + video.gl_get_proc_address("glGetIntegerv") + ); + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); + } + eprintln!("get_framebuffer_binding: {}", fbo); + fbo + } + + fn call_context_reset(&self) -> Option<()> { + self.hw_context_reset_fn.map(|f| unsafe { f(); }) + } + + fn call_context_destroy(&self) -> Option<()> { + self.hw_context_destroy_fn.map(|f| unsafe { f(); }) + } } impl RetroCallbacks for SimpleSdl2OpenglComponent { @@ -71,23 +85,31 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent { self.hw_context_reset_fn.replace(hw_render_callback.context_reset); self.hw_context_destroy_fn.replace(hw_render_callback.context_destroy); - self.hw_context_reset_fn.map(|f| unsafe { f() }); + self.call_context_reset(); Some(true) } - /* + fn get_variable(&mut self, key: &str) -> Option { + match key { + "parallel-n64-gfxplugin" => Some("glide64".to_string()), + _ => None, + } + } + fn set_system_av_info(&mut self, av_info: &SystemAvInfo) -> Option { - self.set_geometry(&av_info.geometry); + self.set_geometry(&av_info.geometry)?; Some(true) } fn set_geometry(&mut self, geom: &GameGeometry) -> Option { - 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.window.set_size(geom.base_width, geom.base_height).ok()?; + self.call_context_destroy()?; + self.gl_context = self.window.gl_create_context().ok()?; + self.window_fbo = Self::current_framebuffer_binding(self.window.subsystem()); + self.call_context_reset()?; Some(true) } - */ fn hw_get_current_framebuffer(&mut self) -> Option { Some(self.window_fbo as usize)