fix incorrect early uses of get_system_av_info (pre-load_game it is not valid)

This commit is contained in:
lifning 2021-11-03 18:11:14 -07:00
parent a42aa936fe
commit 344d88f26b
5 changed files with 47 additions and 23 deletions

View File

@ -41,7 +41,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut sdl_context = sdl2::init()?;
emu.register_component(StderrLogComponent { prefix: "{log} ".to_string() })?;
let mut stderr_log = StderrLogComponent::default();
stderr_log.prefix = "{log} ".to_string();
emu.register_component(stderr_log)?;
// must register before opengl so it can have priority in queries about what N64 plugin to use
// (only supports software-rendered 2D frames currently)
@ -60,8 +62,7 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
emu.register_component(SimpleSdl2GamepadComponent::new(&mut sdl_context))?;
let sleep_fps = SleepFramerateLimitComponent::new(emu.libretro_core());
emu.register_component(sleep_fps)?;
emu.register_component(SleepFramerateLimitComponent::new())?;
emu.register_component(PathBufComponent {
sys_path: opt.system.clone(),

View File

@ -54,25 +54,28 @@ impl RetroCallbacks for SimpleSdl2AudioComponent {
}
impl RetroComponent for SimpleSdl2AudioComponent {
fn post_load_game(&mut self, _retro: &mut LibretroWrapper, _rom: &Path) -> Result<(), Box<dyn Error>> {
fn post_load_game(&mut self, retro: &mut LibretroWrapper, _rom: &Path) -> Result<(), Box<dyn Error>> {
self.src_freq = retro.get_system_av_info().timing.sample_rate;
self.queue.resume();
Ok(())
}
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
if let Ok(converter) = Self::make_converter(self.src_freq, self.queue.spec()) {
let mut samples = std::mem::take(&mut self.audio_buffer);
samples = resample(&converter, samples);
self.audio_buffer = samples;
self.queue.queue(&self.audio_buffer);
self.audio_buffer.clear();
if !self.audio_buffer.is_empty() {
let mut samples = std::mem::take(&mut self.audio_buffer);
samples = resample(&converter, samples);
self.audio_buffer = samples;
self.queue.queue(&self.audio_buffer);
self.audio_buffer.clear();
}
}
ControlFlow::Continue
}
}
impl SimpleSdl2AudioComponent {
pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Result<Self, Box<dyn std::error::Error>> {
pub fn new(sdl_context: &mut Sdl, _retro: &LibretroWrapper) -> Result<Self, Box<dyn std::error::Error>> {
let audio = sdl_context.audio().unwrap();
let desired_spec = AudioSpecDesired {
freq: None,
@ -82,12 +85,8 @@ impl SimpleSdl2AudioComponent {
let queue = AudioQueue::open_queue(&audio, None, &desired_spec)?;
let mut src_freq = retro.get_system_av_info().timing.sample_rate;
// HACK: some cores don't report this 'til we get an env call to set_system_av_info,
// so we can just default to the old libsnes default value.
if src_freq == 0.0 {
src_freq = 32040.5;
}
// default to the old libsnes default value until after load_game or set_system_av_info.
let src_freq = 32040.5;
Ok(SimpleSdl2AudioComponent {
src_freq,

View File

@ -6,6 +6,7 @@ use std::os::raw::c_uint;
use sdl2::Sdl;
use sdl2::rect::Rect;
use sdl2::render::WindowCanvas;
use std::path::Path;
/// Create a root window in SDL2 with an OpenGL context and attaches libretro's
/// `hw_get_proc_address` calls to that of the [sdl2::VideoSubsystem].
@ -34,12 +35,12 @@ impl SimpleSdl2OpenglComponent {
unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy()
);
let geometry = retro.get_system_av_info().geometry;
let pixel_format = sdl2::pixels::PixelFormatEnum::ARGB1555;
let video = sdl_context.video()?;
// default to old libsnes 256x224 window size until load_game (prereq of get_system_av_info)
let window = video
.window(title.as_str(), geometry.base_width, geometry.base_height)
.window(title.as_str(), 256, 224)
.opengl()
.build()?;
@ -90,7 +91,13 @@ impl SimpleSdl2OpenglComponent {
}
}
impl RetroComponent for SimpleSdl2OpenglComponent {}
impl RetroComponent for SimpleSdl2OpenglComponent {
fn post_load_game(&mut self, retro: &mut LibretroWrapper, _rom: &Path) -> crate::base::Result<()> {
self.set_geometry(&retro.get_system_av_info().geometry);
Ok(())
}
}
impl RetroCallbacks for SimpleSdl2OpenglComponent {
fn video_refresh(&mut self, frame: &VideoFrame) {
match frame {

View File

@ -2,6 +2,7 @@ use crate::base::ControlFlow;
use crate::prelude::*;
use std::time::{Duration, Instant};
use std::path::Path;
/// Uses [std::thread::sleep] to maintain the target FPS specified by the core.
///
@ -14,6 +15,10 @@ pub struct SleepFramerateLimitComponent {
}
impl RetroComponent for SleepFramerateLimitComponent {
fn post_load_game(&mut self, retro: &mut LibretroWrapper, _rom: &Path) -> crate::base::Result<()> {
self.fps = retro.get_system_av_info().timing.fps;
Ok(())
}
fn pre_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
self.did_sleep = false;
ControlFlow::Continue
@ -38,11 +43,11 @@ impl RetroCallbacks for SleepFramerateLimitComponent {
}
impl SleepFramerateLimitComponent {
pub fn new(retro: &mut LibretroWrapper) -> Self {
pub fn new() -> Self {
SleepFramerateLimitComponent {
did_sleep: false,
started_video: false,
fps: retro.get_system_av_info().timing.fps,
fps: 60.0, // default until load_game
frame_begin: Instant::now(),
}
}

View File

@ -6,17 +6,29 @@ use std::os::raw::c_uint;
use std::path::PathBuf;
/// Write's the core's own log statements to stderr.
#[derive(Default)]
pub struct StderrLogComponent {
/// May be set to add a prefix to each logged line.
pub prefix: String,
/// The most verbose log level that should be printed.
pub level: ferretro_base::retro::ffi::LogLevel,
}
impl Default for StderrLogComponent {
fn default() -> Self {
StderrLogComponent {
prefix: String::new(),
level: ferretro_base::retro::ffi::LogLevel::Info,
}
}
}
impl RetroComponent for StderrLogComponent {}
impl RetroCallbacks for StderrLogComponent {
fn log_print(&mut self, level: ferretro_base::retro::ffi::LogLevel, msg: &str) {
eprint!("{}[{:?}] {}", self.prefix, level, msg);
if level >= self.level {
eprint!("{}[{:?}] {}", self.prefix, level, msg);
}
}
}