diff --git a/ferretro_components/Cargo.toml b/ferretro_components/Cargo.toml index 135374b..a848122 100644 --- a/ferretro_components/Cargo.toml +++ b/ferretro_components/Cargo.toml @@ -13,6 +13,7 @@ libloading = "0.5" num_enum = "0.4" ffmpeg-next = { version = "4.3.8", optional = true } sdl2 = { version = "0.32", optional = true } +gl = { version = "0.14", optional = true } crossbeam-channel = { version = "0.4", optional = true } [dev-dependencies] @@ -21,4 +22,4 @@ structopt = "0.3" [features] ffmpeg_comp = ["ffmpeg-next"] -sdl2_comp = ["sdl2", "crossbeam-channel"] +sdl2_comp = ["sdl2", "gl", "crossbeam-channel"] diff --git a/ferretro_components/src/provided/sdl2/canvas.rs b/ferretro_components/src/provided/sdl2/canvas.rs index 18ab497..ac9e71a 100644 --- a/ferretro_components/src/provided/sdl2/canvas.rs +++ b/ferretro_components/src/provided/sdl2/canvas.rs @@ -12,7 +12,7 @@ pub struct SimpleSdl2CanvasComponent { } impl SimpleSdl2CanvasComponent { - pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Self { + pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Result> { let sys_info = retro.get_system_info(); let title = format!( "{} - ferretro SDL", @@ -23,19 +23,16 @@ impl SimpleSdl2CanvasComponent { let pixel_format = sdl2::pixels::PixelFormatEnum::ARGB1555; let window = sdl_context - .video() - .unwrap() + .video()? .window(title.as_str(), geometry.base_width, geometry.base_height) - .opengl() - .build() - .unwrap(); + .build()?; - let canvas = window.into_canvas().build().unwrap(); + let canvas = window.into_canvas().build()?; - SimpleSdl2CanvasComponent { + Ok(SimpleSdl2CanvasComponent { canvas, pixel_format, - } + }) } } diff --git a/ferretro_components/src/provided/sdl2/opengl.rs b/ferretro_components/src/provided/sdl2/opengl.rs index 3790344..b91bbb3 100644 --- a/ferretro_components/src/provided/sdl2/opengl.rs +++ b/ferretro_components/src/provided/sdl2/opengl.rs @@ -7,10 +7,6 @@ use sdl2::Sdl; use sdl2::rect::Rect; use sdl2::render::WindowCanvas; -// TODO: get these from somewhere better without pulling in too much of a mess for the sdl2 feature -const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6; -const GL_COLOR_BUFFER_BIT: c_uint = 0x00004000; - #[allow(non_snake_case)] pub struct SimpleSdl2OpenglComponent { canvas: WindowCanvas, @@ -55,7 +51,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. // SDL_CreateRenderer, called by CanvasBuilder::build, creates a new GL Context. - let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); fbo }; + let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(gl::FRAMEBUFFER_BINDING, &mut fbo); fbo }; Ok(SimpleSdl2OpenglComponent { canvas, @@ -72,7 +68,7 @@ impl SimpleSdl2OpenglComponent { let mut fbo: c_uint = 0; unsafe { #[allow(non_snake_case)] - (self.glGetIntegerv)(GL_FRAMEBUFFER_BINDING, &mut fbo); + (self.glGetIntegerv)(gl::FRAMEBUFFER_BINDING, &mut fbo); } fbo } @@ -105,7 +101,7 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent { fn video_refresh_hw(&mut self, _width: c_uint, _height: c_uint) { self.canvas.present(); - unsafe { (self.glClear)(GL_COLOR_BUFFER_BIT); } + unsafe { (self.glClear)(gl::COLOR_BUFFER_BIT); } } fn set_pixel_format(&mut self, pix_fmt: PixelFormat) -> Option { @@ -119,6 +115,10 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent { // TODO: depth, stencil, cache_context, bottom_left_origin? fn set_hw_render(&mut self, hw_render_callback: &HwRenderCallback) -> Option { + self.canvas.window().subsystem().gl_attr().set_context_version( + hw_render_callback.version_major as u8, + hw_render_callback.version_minor as u8, + ); self.hw_context_reset_fn.replace(hw_render_callback.context_reset); self.hw_context_destroy_fn.replace(hw_render_callback.context_destroy); self.call_context_reset(); @@ -138,29 +138,10 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent { } 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); + eprintln!("set_geometry({:?})", geom); + let _ = self.canvas.window_mut().set_size(geom.base_width, geom.base_height).ok()?; + let _ = self.canvas.set_logical_size(geom.base_width, geom.base_height).ok()?; self.window_fbo = self.current_framebuffer_binding(); - /* - let mut old_canvas = unsafe { MaybeUninit::uninit().assume_init() }; - std::mem::swap(&mut old_canvas, &mut self.canvas); - - // no funny ? operators here because we've got uninitialized memory in self.canvas! - let mut window = old_canvas.into_window(); - window.set_size(geom.base_width, geom.base_height).unwrap(); - self.call_context_destroy().unwrap(); - let mut new_canvas = window.into_canvas() - .accelerated() - .target_texture() - .build() - .unwrap(); - self.window_fbo = self.current_framebuffer_binding(); - - std::mem::swap(&mut self.canvas, &mut new_canvas); - std::mem::forget(new_canvas); - - self.call_context_reset()?; - */ Some(true) }