fix a couple minor sdl a/v bugs

This commit is contained in:
lifning 2021-12-11 01:38:48 -08:00
parent b8cc606bd5
commit 709a23307a
3 changed files with 47 additions and 27 deletions

View File

@ -69,6 +69,7 @@ impl RetroComponent for SimpleSdl2AudioComponent {
} }
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow { fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
if self.src_freq != 0.0 {
match Self::make_converter(self.src_freq, self.queue.spec()) { match Self::make_converter(self.src_freq, self.queue.spec()) {
Ok(converter) => { Ok(converter) => {
if !self.audio_buffer.is_empty() { if !self.audio_buffer.is_empty() {
@ -85,6 +86,9 @@ impl RetroComponent for SimpleSdl2AudioComponent {
ControlFlow::Break ControlFlow::Break
} }
} }
} else {
ControlFlow::Continue
}
} }
} }

View File

@ -4,6 +4,7 @@ use std::ffi::CStr;
use std::path::Path; use std::path::Path;
use sdl2::Sdl; use sdl2::Sdl;
use sdl2::pixels::PixelFormatEnum;
use sdl2::render::WindowCanvas; use sdl2::render::WindowCanvas;
use sdl2::video::FullscreenType; use sdl2::video::FullscreenType;
@ -45,8 +46,8 @@ pub(crate) fn sdl2_pixfmt(retro_fmt: PixelFormat) -> sdl2::pixels::PixelFormatEn
} }
pub(crate) fn frame_to_surface<'a>(frame: &'a VideoFrame) -> crate::base::Result<sdl2::surface::Surface<'a>> { pub(crate) fn frame_to_surface<'a>(frame: &'a VideoFrame) -> crate::base::Result<sdl2::surface::Surface<'a>> {
let (bytes, pitch) = frame.data_pitch_as_bytes().unwrap();
let (width, height) = frame.dimensions(); let (width, height) = frame.dimensions();
if let Some((bytes, pitch)) = frame.data_pitch_as_bytes() {
let pixel_format = frame let pixel_format = frame
.pixel_format() .pixel_format()
.map(sdl2_pixfmt) .map(sdl2_pixfmt)
@ -58,6 +59,14 @@ pub(crate) fn frame_to_surface<'a>(frame: &'a VideoFrame) -> crate::base::Result
}; };
sdl2::surface::Surface::from_data(data, width, height, pitch as u32, pixel_format) sdl2::surface::Surface::from_data(data, width, height, pitch as u32, pixel_format)
.map_err(Into::into) .map_err(Into::into)
} else {
let pixel_format = frame
.pixel_format()
.map(sdl2_pixfmt)
.unwrap_or(PixelFormatEnum::ARGB8888);
sdl2::surface::Surface::new(width, height, pixel_format)
.map_err(Into::into)
}
} }
/// Creates a root window in SDL2, then displays each 2D video frame provided by the core /// Creates a root window in SDL2, then displays each 2D video frame provided by the core

View File

@ -5,6 +5,7 @@ use std::os::raw::c_uint;
use std::path::Path; use std::path::Path;
use sdl2::Sdl; use sdl2::Sdl;
use sdl2::rect::Rect;
use sdl2::render::WindowCanvas; use sdl2::render::WindowCanvas;
use sdl2::video::FullscreenType; use sdl2::video::FullscreenType;
@ -100,7 +101,6 @@ impl RetroComponent for SimpleSdl2OpenglComponent {
rom.file_stem().unwrap_or_default().to_string_lossy(), rom.file_stem().unwrap_or_default().to_string_lossy(),
); );
self.canvas.window_mut().set_title(&title)?; self.canvas.window_mut().set_title(&title)?;
self.canvas.window_mut().show();
self.set_geometry(&retro.get_system_av_info().geometry); self.set_geometry(&retro.get_system_av_info().geometry);
Ok(()) Ok(())
} }
@ -108,14 +108,21 @@ impl RetroComponent for SimpleSdl2OpenglComponent {
impl RetroCallbacks for SimpleSdl2OpenglComponent { impl RetroCallbacks for SimpleSdl2OpenglComponent {
fn video_refresh(&mut self, frame: &VideoFrame) { fn video_refresh(&mut self, frame: &VideoFrame) {
self.canvas.window_mut().show();
let output_size = self.canvas.output_size().unwrap();
match frame { match frame {
VideoFrame::HardwareRender { .. } => { VideoFrame::HardwareRender { .. } => {
if output_size != self.win_size {
let (w, h) = output_size;
// FIXME: this isn't enough - need core to render to texture that we just scale
self.canvas.set_viewport(Rect::new(0, 0, w, h));
self.win_size = output_size;
}
self.canvas.present(); self.canvas.present();
unsafe { (self.glClear)(gl::COLOR_BUFFER_BIT); } unsafe { (self.glClear)(gl::COLOR_BUFFER_BIT); }
} }
VideoFrame::Duplicate { .. } => {} VideoFrame::Duplicate { .. } => {}
_ => { _ => {
let output_size = self.canvas.output_size().unwrap();
if output_size != self.win_size { if output_size != self.win_size {
self.canvas.clear(); self.canvas.clear();
self.win_size = output_size; self.win_size = output_size;