fix incorrect early uses of get_system_av_info (pre-load_game it is not valid)
This commit is contained in:
parent
a42aa936fe
commit
344d88f26b
|
@ -41,7 +41,9 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let mut sdl_context = sdl2::init()?;
|
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
|
// must register before opengl so it can have priority in queries about what N64 plugin to use
|
||||||
// (only supports software-rendered 2D frames currently)
|
// (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))?;
|
emu.register_component(SimpleSdl2GamepadComponent::new(&mut sdl_context))?;
|
||||||
|
|
||||||
let sleep_fps = SleepFramerateLimitComponent::new(emu.libretro_core());
|
emu.register_component(SleepFramerateLimitComponent::new())?;
|
||||||
emu.register_component(sleep_fps)?;
|
|
||||||
|
|
||||||
emu.register_component(PathBufComponent {
|
emu.register_component(PathBufComponent {
|
||||||
sys_path: opt.system.clone(),
|
sys_path: opt.system.clone(),
|
||||||
|
|
|
@ -54,25 +54,28 @@ impl RetroCallbacks for SimpleSdl2AudioComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RetroComponent 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();
|
self.queue.resume();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
fn post_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
||||||
if let Ok(converter) = Self::make_converter(self.src_freq, self.queue.spec()) {
|
if let Ok(converter) = Self::make_converter(self.src_freq, self.queue.spec()) {
|
||||||
|
if !self.audio_buffer.is_empty() {
|
||||||
let mut samples = std::mem::take(&mut self.audio_buffer);
|
let mut samples = std::mem::take(&mut self.audio_buffer);
|
||||||
samples = resample(&converter, samples);
|
samples = resample(&converter, samples);
|
||||||
self.audio_buffer = samples;
|
self.audio_buffer = samples;
|
||||||
self.queue.queue(&self.audio_buffer);
|
self.queue.queue(&self.audio_buffer);
|
||||||
self.audio_buffer.clear();
|
self.audio_buffer.clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ControlFlow::Continue
|
ControlFlow::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimpleSdl2AudioComponent {
|
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 audio = sdl_context.audio().unwrap();
|
||||||
let desired_spec = AudioSpecDesired {
|
let desired_spec = AudioSpecDesired {
|
||||||
freq: None,
|
freq: None,
|
||||||
|
@ -82,12 +85,8 @@ impl SimpleSdl2AudioComponent {
|
||||||
|
|
||||||
let queue = AudioQueue::open_queue(&audio, None, &desired_spec)?;
|
let queue = AudioQueue::open_queue(&audio, None, &desired_spec)?;
|
||||||
|
|
||||||
let mut src_freq = retro.get_system_av_info().timing.sample_rate;
|
// default to the old libsnes default value until after load_game or set_system_av_info.
|
||||||
// HACK: some cores don't report this 'til we get an env call to set_system_av_info,
|
let src_freq = 32040.5;
|
||||||
// so we can just default to the old libsnes default value.
|
|
||||||
if src_freq == 0.0 {
|
|
||||||
src_freq = 32040.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(SimpleSdl2AudioComponent {
|
Ok(SimpleSdl2AudioComponent {
|
||||||
src_freq,
|
src_freq,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::os::raw::c_uint;
|
||||||
use sdl2::Sdl;
|
use sdl2::Sdl;
|
||||||
use sdl2::rect::Rect;
|
use sdl2::rect::Rect;
|
||||||
use sdl2::render::WindowCanvas;
|
use sdl2::render::WindowCanvas;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
/// Create a root window in SDL2 with an OpenGL context and attaches libretro's
|
/// 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].
|
/// `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()
|
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 pixel_format = sdl2::pixels::PixelFormatEnum::ARGB1555;
|
||||||
|
|
||||||
let video = sdl_context.video()?;
|
let video = sdl_context.video()?;
|
||||||
|
// default to old libsnes 256x224 window size until load_game (prereq of get_system_av_info)
|
||||||
let window = video
|
let window = video
|
||||||
.window(title.as_str(), geometry.base_width, geometry.base_height)
|
.window(title.as_str(), 256, 224)
|
||||||
.opengl()
|
.opengl()
|
||||||
.build()?;
|
.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 {
|
impl RetroCallbacks for SimpleSdl2OpenglComponent {
|
||||||
fn video_refresh(&mut self, frame: &VideoFrame) {
|
fn video_refresh(&mut self, frame: &VideoFrame) {
|
||||||
match frame {
|
match frame {
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::base::ControlFlow;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
/// Uses [std::thread::sleep] to maintain the target FPS specified by the core.
|
/// Uses [std::thread::sleep] to maintain the target FPS specified by the core.
|
||||||
///
|
///
|
||||||
|
@ -14,6 +15,10 @@ pub struct SleepFramerateLimitComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RetroComponent for 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 {
|
fn pre_run(&mut self, _retro: &mut LibretroWrapper) -> ControlFlow {
|
||||||
self.did_sleep = false;
|
self.did_sleep = false;
|
||||||
ControlFlow::Continue
|
ControlFlow::Continue
|
||||||
|
@ -38,11 +43,11 @@ impl RetroCallbacks for SleepFramerateLimitComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SleepFramerateLimitComponent {
|
impl SleepFramerateLimitComponent {
|
||||||
pub fn new(retro: &mut LibretroWrapper) -> Self {
|
pub fn new() -> Self {
|
||||||
SleepFramerateLimitComponent {
|
SleepFramerateLimitComponent {
|
||||||
did_sleep: false,
|
did_sleep: false,
|
||||||
started_video: false,
|
started_video: false,
|
||||||
fps: retro.get_system_av_info().timing.fps,
|
fps: 60.0, // default until load_game
|
||||||
frame_begin: Instant::now(),
|
frame_begin: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,31 @@ use std::os::raw::c_uint;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// Write's the core's own log statements to stderr.
|
/// Write's the core's own log statements to stderr.
|
||||||
#[derive(Default)]
|
|
||||||
pub struct StderrLogComponent {
|
pub struct StderrLogComponent {
|
||||||
/// May be set to add a prefix to each logged line.
|
/// May be set to add a prefix to each logged line.
|
||||||
pub prefix: String,
|
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 RetroComponent for StderrLogComponent {}
|
||||||
|
|
||||||
impl RetroCallbacks for StderrLogComponent {
|
impl RetroCallbacks for StderrLogComponent {
|
||||||
fn log_print(&mut self, level: ferretro_base::retro::ffi::LogLevel, msg: &str) {
|
fn log_print(&mut self, level: ferretro_base::retro::ffi::LogLevel, msg: &str) {
|
||||||
|
if level >= self.level {
|
||||||
eprint!("{}[{:?}] {}", self.prefix, level, msg);
|
eprint!("{}[{:?}] {}", self.prefix, level, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Writes all the input descriptors, variables, and subsystem information to stderr as they are
|
/// Writes all the input descriptors, variables, and subsystem information to stderr as they are
|
||||||
/// provided by the core.
|
/// provided by the core.
|
||||||
|
|
Loading…
Reference in New Issue