From 7b06ed61d1ad867378531f1273cb16c6a6b66c0d Mon Sep 17 00:00:00 2001 From: lifning <> Date: Wed, 11 Aug 2021 01:08:22 -0700 Subject: [PATCH] constructor for RetroComponentBase --- examples/sdl2_emulator.rs | 8 +++--- src/components/mod.rs | 21 ++++++++++++++- src/retro/loading.rs | 54 +++++++++++++++++++-------------------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/examples/sdl2_emulator.rs b/examples/sdl2_emulator.rs index eda1978..0ae554a 100644 --- a/examples/sdl2_emulator.rs +++ b/examples/sdl2_emulator.rs @@ -285,7 +285,7 @@ impl retro::wrapper::RetroCallbacks for MyEmulator { } } - fn set_variables(&mut self, variables: Vec) -> bool { + fn set_variables(&mut self, variables: &Vec) -> bool { for v in variables { eprintln!("{:?}", v); } @@ -311,12 +311,12 @@ impl retro::wrapper::RetroCallbacks for MyEmulator { true } - fn set_subsystem_info(&mut self, subsystem_info: Vec) -> bool { + fn set_subsystem_info(&mut self, subsystem_info: &Vec) -> bool { println!("subsystem info: {:?}", subsystem_info); true } - fn set_controller_info(&mut self, controller_info: Vec) -> bool { + fn set_controller_info(&mut self, controller_info: &Vec) -> bool { for ci in controller_info { // so we can have analog support in beetle/mednafen saturn if ci.name.as_str() == "3D Control Pad" { @@ -327,7 +327,7 @@ impl retro::wrapper::RetroCallbacks for MyEmulator { true } - fn set_input_descriptors(&mut self, descriptors: Vec) -> bool { + fn set_input_descriptors(&mut self, descriptors: &Vec) -> bool { for id in descriptors { println!("{:?}", id); } diff --git a/src/components/mod.rs b/src/components/mod.rs index 97a9754..2cb0116 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,13 +1,32 @@ use crate::prelude::*; use crate::retro::ffi::*; use std::os::raw::c_uint; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; +use std::pin::Pin; pub struct RetroComponentBase { retro: LibretroWrapper, pub components: Vec>, } +impl RetroComponentBase { + pub fn new(core_path: impl AsRef) -> Pin> { + let lib = libloading::Library::new(core_path.as_ref()).unwrap(); + let raw_retro = crate::retro::loading::LibretroApi::from_library(lib).unwrap(); + let retro = LibretroWrapper::from(raw_retro); + + let emu = RetroComponentBase { + retro, + components: Vec::new(), + }; + + let mut pin_emu = Box::pin(emu); + crate::retro::wrapper::set_handler(pin_emu.as_mut()); + pin_emu.retro.init(); + pin_emu + } +} + impl LibretroWrapperAccess for RetroComponentBase { fn libretro_core(&mut self) -> &mut LibretroWrapper { &mut self.retro diff --git a/src/retro/loading.rs b/src/retro/loading.rs index a0da355..9f889f8 100644 --- a/src/retro/loading.rs +++ b/src/retro/loading.rs @@ -49,7 +49,7 @@ impl LibretroApi { pub fn set_environment(&self, cb: EnvironmentFn) { unsafe { (&self.core_api.retro_set_environment)(cb) } } - /// video_refresh() must be called before run(). + /// set_video_refresh() must be called before run(). pub fn set_video_refresh(&self, cb: VideoRefreshFn) { unsafe { (&self.core_api.retro_set_video_refresh)(cb) } } @@ -85,11 +85,11 @@ impl LibretroApi { info } } - /** Gets information about system audio/video timings and geometry. - * Can be called only after load_game() has successfully completed. - * NOTE: The implementation of this function might not initialize every variable if needed. - * E.g. geom.aspect_ratio might not be initialized if core doesn't - * desire a particular aspect ratio. */ + /// Gets information about system audio/video timings and geometry. + /// Can be called only after load_game() has successfully completed. + /// NOTE: The implementation of this function might not initialize every variable if needed. + /// E.g. geom.aspect_ratio might not be initialized if core doesn't + /// desire a particular aspect ratio. pub fn get_system_av_info(&self) -> SystemAvInfo { unsafe { let mut av_info = ::std::mem::zeroed::(); @@ -97,20 +97,19 @@ impl LibretroApi { av_info } } - /** Sets device to be used for player 'port'. - * By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all - * available ports. - * Setting a particular device type is not a guarantee that libretro cores - * will only poll input based on that particular device type. It is only a - * hint to the libretro core when a core cannot automatically detect the - * appropriate input device type on its own. It is also relevant when a - * core can change its behavior depending on device type. - * - * As part of the core's implementation of retro_set_controller_port_device, - * the core should call RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS to notify the - * frontend if the descriptions for any controls have changed as a - * result of changing the device type. - */ + /// Sets device to be used for player 'port'. + /// By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all + /// available ports. + /// Setting a particular device type is not a guarantee that libretro cores + /// will only poll input based on that particular device type. It is only a + /// hint to the libretro core when a core cannot automatically detect the + /// appropriate input device type on its own. It is also relevant when a + /// core can change its behavior depending on device type. + /// + /// As part of the core's implementation of retro_set_controller_port_device, + /// the core should call RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS to notify the + /// frontend if the descriptions for any controls have changed as a + /// result of changing the device type. pub fn set_controller_port_device(&self, port: u32, device: u32) { unsafe { (&self.core_api.retro_set_controller_port_device)(port, device) } } @@ -118,14 +117,13 @@ impl LibretroApi { pub fn reset(&self) { unsafe { (&self.core_api.retro_reset)() } } - /** Runs the game for one video frame. - * During retro_run(), input_poll callback must be called at least once. - * - * If a frame is not rendered for reasons where a game "dropped" a frame, - * this still counts as a frame, and retro_run() should explicitly dupe - * a frame if GET_CAN_DUPE returns true. - * In this case, the video callback can take a NULL argument for data. - */ + /// Runs the game for one video frame. + /// During retro_run(), input_poll callback must be called at least once. + /// + /// If a frame is not rendered for reasons where a game "dropped" a frame, + /// this still counts as a frame, and retro_run() should explicitly dupe + /// a frame if GET_CAN_DUPE returns true. + /// In this case, the video callback can take a NULL argument for data. pub fn run(&self) { unsafe { (&self.core_api.retro_run)() } }