Fix infinite drop() loop on close
This commit is contained in:
parent
d9f1d789ca
commit
3157fbdac1
|
@ -3,7 +3,7 @@ extern crate rustro;
|
|||
extern crate sdl2;
|
||||
|
||||
use rustro::retro;
|
||||
use rustro::retro::ffi::{GameGeometry, SystemAvInfo};
|
||||
use rustro::retro::ffi::{GameGeometry, SystemInfo, SystemAvInfo};
|
||||
use rustro::retro::constants::{Input, DeviceIndex, JoypadButton, AnalogAxis};
|
||||
|
||||
use std::ffi::CStr;
|
||||
|
@ -24,6 +24,7 @@ use sdl2::video::WindowContext;
|
|||
|
||||
struct MyEmulator {
|
||||
retro: retro::wrapper::LibretroWrapper,
|
||||
sys_info: SystemInfo,
|
||||
av_info: SystemAvInfo,
|
||||
|
||||
sdl_context: sdl2::Sdl,
|
||||
|
@ -50,10 +51,10 @@ impl MyEmulator {
|
|||
let raw_retro = retro::loading::LibretroApi::from_library(lib).unwrap();
|
||||
let retro = retro::wrapper::LibretroWrapper::from(raw_retro);
|
||||
|
||||
let sys_info = retro.as_ref().get_system_info();
|
||||
let title = format!(
|
||||
"{} - rust libretro",
|
||||
unsafe { CStr::from_ptr(retro.as_ref().get_system_info().library_name) }
|
||||
.to_string_lossy()
|
||||
unsafe { CStr::from_ptr(sys_info.library_name) }.to_string_lossy()
|
||||
);
|
||||
|
||||
let mut av_info = retro.as_ref().get_system_av_info();
|
||||
|
@ -115,6 +116,7 @@ impl MyEmulator {
|
|||
let emu = MyEmulator {
|
||||
retro,
|
||||
av_info,
|
||||
sys_info,
|
||||
sdl_context,
|
||||
canvas,
|
||||
pixel_format,
|
||||
|
@ -160,16 +162,19 @@ impl MyEmulator {
|
|||
}
|
||||
|
||||
pub fn load_game(&self, rom: impl AsRef<Path>) {
|
||||
let path = rom.as_ref();
|
||||
let mut data = None;
|
||||
let mut v = Vec::new();
|
||||
if let Ok(mut f) = std::fs::File::open(rom.as_ref()) {
|
||||
if f.read_to_end(&mut v).is_ok() {
|
||||
data = Some(v.as_ref());
|
||||
if !self.sys_info.need_fullpath {
|
||||
if let Ok(mut f) = std::fs::File::open(path) {
|
||||
if f.read_to_end(&mut v).is_ok() {
|
||||
data = Some(v.as_ref());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.retro
|
||||
.as_ref()
|
||||
.load_game(Some(rom.as_ref()), data, None)
|
||||
.load_game(Some(path), data, None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
|
@ -182,6 +187,13 @@ impl MyEmulator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MyEmulator {
|
||||
fn drop(&mut self) {
|
||||
retro::wrapper::unset_handler();
|
||||
}
|
||||
}
|
||||
|
||||
impl retro::wrapper::Handler for MyEmulator {
|
||||
fn video_refresh(&mut self, data: &[u8], width: u32, height: u32, pitch: u32) {
|
||||
let rect = Rect::new(0, 0, width, height);
|
||||
|
@ -248,16 +260,16 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
|
||||
fn set_system_av_info(&mut self, av_info: SystemAvInfo) -> bool {
|
||||
let (width, height) = (av_info.geometry.base_width, av_info.geometry.base_height);
|
||||
self.canvas.window_mut().set_size(width, height);
|
||||
self.canvas.set_logical_size(width, height);
|
||||
let _ = self.canvas.window_mut().set_size(width, height);
|
||||
let _ = self.canvas.set_logical_size(width, height);
|
||||
self.av_info = av_info;
|
||||
true
|
||||
}
|
||||
|
||||
fn set_geometry(&mut self, geom: GameGeometry) -> bool {
|
||||
let (width, height) = (geom.base_width, geom.base_height);
|
||||
self.canvas.window_mut().set_size(width, height);
|
||||
self.canvas.set_logical_size(width, height);
|
||||
let _ = self.canvas.window_mut().set_size(width, height);
|
||||
let _ = self.canvas.set_logical_size(width, height);
|
||||
self.av_info.geometry = geom;
|
||||
true
|
||||
}
|
||||
|
|
|
@ -207,11 +207,6 @@ impl StaticCallbacks {
|
|||
None => 0,
|
||||
}
|
||||
}
|
||||
pub(crate) fn reset() {
|
||||
unsafe {
|
||||
CB_SINGLETON.handler.take();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LibretroWrapper {
|
||||
|
@ -237,12 +232,6 @@ impl AsRef<LibretroApi> for LibretroWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for LibretroWrapper {
|
||||
fn drop(&mut self) {
|
||||
StaticCallbacks::reset();
|
||||
}
|
||||
}
|
||||
|
||||
// a note on lifetimes: we explicitly lie about them here because as long as they live as long as
|
||||
// the library wrapper itself we're good (we wipe our 'static references on drop() too)
|
||||
pub fn set_handler(handler: Pin<&'_ mut (dyn Handler + '_)>) {
|
||||
|
@ -251,3 +240,9 @@ pub fn set_handler(handler: Pin<&'_ mut (dyn Handler + '_)>) {
|
|||
CB_SINGLETON.handler.replace(Pin::new_unchecked(ptr.as_mut().unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset_handler() {
|
||||
unsafe {
|
||||
CB_SINGLETON.handler.take();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue