fix a couple minor sdl a/v bugs
This commit is contained in:
parent
b8cc606bd5
commit
709a23307a
|
@ -69,21 +69,25 @@ impl RetroComponent for SimpleSdl2AudioComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
||||||
match Self::make_converter(self.src_freq, self.queue.spec()) {
|
if self.src_freq != 0.0 {
|
||||||
Ok(converter) => {
|
match Self::make_converter(self.src_freq, self.queue.spec()) {
|
||||||
if !self.audio_buffer.is_empty() {
|
Ok(converter) => {
|
||||||
let mut samples = std::mem::take(&mut self.audio_buffer);
|
if !self.audio_buffer.is_empty() {
|
||||||
samples = resample(&converter, samples);
|
let mut samples = std::mem::take(&mut self.audio_buffer);
|
||||||
self.audio_buffer = samples;
|
samples = resample(&converter, samples);
|
||||||
self.queue.queue(&self.audio_buffer);
|
self.audio_buffer = samples;
|
||||||
self.audio_buffer.clear();
|
self.queue.queue(&self.audio_buffer);
|
||||||
|
self.audio_buffer.clear();
|
||||||
|
}
|
||||||
|
ControlFlow::Continue
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Audio sample rate conversion failed: {:?}", e);
|
||||||
|
ControlFlow::Break
|
||||||
}
|
}
|
||||||
ControlFlow::Continue
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Audio sample rate conversion failed: {:?}", e);
|
|
||||||
ControlFlow::Break
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ControlFlow::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,19 +46,27 @@ 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();
|
||||||
let pixel_format = frame
|
if let Some((bytes, pitch)) = frame.data_pitch_as_bytes() {
|
||||||
.pixel_format()
|
let pixel_format = frame
|
||||||
.map(sdl2_pixfmt)
|
.pixel_format()
|
||||||
.ok_or("Unknown pixel format")?;
|
.map(sdl2_pixfmt)
|
||||||
// dirty, but must be &mut for SDL API.
|
.ok_or("Unknown pixel format")?;
|
||||||
// safe as long as we don't offer a &mut Surface in the public API.
|
// dirty, but must be &mut for SDL API.
|
||||||
let data = unsafe {
|
// safe as long as we don't offer a &mut Surface in the public API.
|
||||||
core::slice::from_raw_parts_mut(bytes.as_ptr() as *mut u8, bytes.len())
|
let data = unsafe {
|
||||||
};
|
core::slice::from_raw_parts_mut(bytes.as_ptr() as *mut u8, bytes.len())
|
||||||
sdl2::surface::Surface::from_data(data, width, height, pitch as u32, pixel_format)
|
};
|
||||||
.map_err(Into::into)
|
sdl2::surface::Surface::from_data(data, width, height, pitch as u32, pixel_format)
|
||||||
|
.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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue