code cleanup
- make joypad a directory module, split retropad implementation into new module (but re-export it). also rename joypad to InputDevice - remove spurious retro_reset (it's not needed and in fact crashes some cores) - rename frontend input device APIs, add one for removing (unplugging) a device
This commit is contained in:
parent
ad634bf1fa
commit
a7544cb64d
6 changed files with 71 additions and 54 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::joypad::Joypad;
|
||||
use crate::input_devices::InputDevice;
|
||||
use crate::libretro_callbacks;
|
||||
use crate::libretro_core_variable::CoreVariable;
|
||||
use crate::result::{Error, Result};
|
||||
|
@ -66,13 +66,19 @@ pub struct Frontend {
|
|||
pub(crate) fb_height: u32,
|
||||
pub(crate) fb_pitch: u32,
|
||||
|
||||
/// The "system" directory. Used for BIOS roms
|
||||
pub(crate) system_directory: CString,
|
||||
|
||||
/// The save directory. Used for saves. (TODO: Should make this per-core!!!)
|
||||
pub(crate) save_directory: CString,
|
||||
|
||||
/// The config directory. Stores configuration for each core.
|
||||
pub(crate) config_directory: String,
|
||||
|
||||
/// Hashmap of core variabels.
|
||||
pub(crate) variables: HashMap<String, CoreVariable>,
|
||||
|
||||
pub(crate) joypads: HashMap<u32 /* port */, *mut dyn Joypad>,
|
||||
pub(crate) joypads: HashMap<u32 /* port */, *mut dyn InputDevice>,
|
||||
|
||||
pub(crate) interface: *mut dyn FrontendInterface,
|
||||
}
|
||||
|
@ -111,7 +117,7 @@ impl Frontend {
|
|||
|
||||
// Assign to the global fronend pointer
|
||||
unsafe {
|
||||
assert!(FRONTEND.is_null(), "Cannot have multiple sir.");
|
||||
assert!(FRONTEND.is_null(), "Cannot have multiple frontends.");
|
||||
FRONTEND = &mut *boxed as *mut Frontend;
|
||||
}
|
||||
|
||||
|
@ -123,7 +129,8 @@ impl Frontend {
|
|||
self.core_library.is_some() && self.core_api.is_some()
|
||||
}
|
||||
|
||||
pub fn set_input_port_device(&mut self, port: u32, device: *mut dyn Joypad) {
|
||||
/// Plugs in an input device to the specified port.
|
||||
pub fn plug_input_device(&mut self, port: u32, device: *mut dyn InputDevice) {
|
||||
if self.core_loaded() {
|
||||
let core_api = self.core_api.as_mut().unwrap();
|
||||
|
||||
|
@ -131,11 +138,28 @@ impl Frontend {
|
|||
(core_api.retro_set_controller_port_device)(port, (*device).device_type());
|
||||
}
|
||||
|
||||
self.joypads.insert(port, device);
|
||||
if !self.joypads.contains_key(&port) {
|
||||
self.joypads.insert(port, device);
|
||||
} else {
|
||||
(*self.joypads.get_mut(&port).unwrap()) = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear_input_port_device?
|
||||
/// Unplugs a input device from the given port.
|
||||
pub fn unplug_input_device(&mut self, port: u32) {
|
||||
if self.core_loaded() {
|
||||
let core_api = self.core_api.as_mut().unwrap();
|
||||
|
||||
unsafe {
|
||||
(core_api.retro_set_controller_port_device)(port, DEVICE_NONE);
|
||||
}
|
||||
|
||||
if !self.joypads.contains_key(&port) {
|
||||
self.joypads.remove(&port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_config_file_path(&self) -> String {
|
||||
let path = unsafe {
|
||||
|
@ -280,8 +304,6 @@ impl Frontend {
|
|||
libretro_callbacks::audio_sample_batch_callback,
|
||||
);
|
||||
|
||||
(core_api_ref.retro_reset)();
|
||||
|
||||
info!("Core {} loaded", path.as_ref().display());
|
||||
|
||||
// Get AV info
|
||||
|
|
17
crates/retro_frontend/src/input_devices/mod.rs
Normal file
17
crates/retro_frontend/src/input_devices/mod.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
//! Input devices
|
||||
pub mod retropad;
|
||||
pub use retropad::*;
|
||||
|
||||
/// Trait for implementing Libretro input devices
|
||||
pub trait InputDevice {
|
||||
// TODO: is_pressed(id: u32)?
|
||||
|
||||
fn device_type(&self) -> u32;
|
||||
|
||||
fn get_button(&self, id: u32) -> i16;
|
||||
|
||||
fn reset(&mut self);
|
||||
|
||||
fn press_button(&mut self, id: u32, pressure: Option<i16>);
|
||||
}
|
||||
|
|
@ -1,23 +1,8 @@
|
|||
//! libretro pad abstraction
|
||||
|
||||
//! RetroPad
|
||||
use super::InputDevice;
|
||||
use crate::libretro_sys_new;
|
||||
|
||||
pub trait Joypad {
|
||||
// TODO: is_pressed(id: u32)?
|
||||
|
||||
fn device_type(&self) -> u32;
|
||||
|
||||
fn get_button(&self, id: u32) -> i16;
|
||||
|
||||
fn reset(&mut self);
|
||||
|
||||
fn press_button(&mut self, id: u32, pressure: Option<i16>);
|
||||
}
|
||||
|
||||
// TODO: Split this into a new module, and make this a dir based one
|
||||
// (mod.rs/retropad.rs/analogpad.rs) once we have AnalogPad support.
|
||||
|
||||
/// Implementation of the [Joypad] trait for the Libretro
|
||||
/// Implementation of the [InputDevice] trait for the Libretro
|
||||
/// RetroPad; which is essentially a standard PS1 controller,
|
||||
/// with a couple more buttons inherited from the Dual Analog/DualShock.
|
||||
pub struct RetroPad {
|
||||
|
@ -30,7 +15,7 @@ impl RetroPad {
|
|||
}
|
||||
}
|
||||
|
||||
impl Joypad for RetroPad {
|
||||
impl InputDevice for RetroPad {
|
||||
fn device_type(&self) -> u32 {
|
||||
libretro_sys_new::DEVICE_JOYPAD
|
||||
}
|
|
@ -6,7 +6,7 @@ mod libretro_log;
|
|||
|
||||
pub mod libretro_sys_new;
|
||||
|
||||
pub mod joypad;
|
||||
pub mod input_devices;
|
||||
pub mod util;
|
||||
|
||||
pub mod frontend;
|
||||
|
|
|
@ -6,13 +6,24 @@ use tracing::*;
|
|||
#[no_mangle]
|
||||
/// This recieves log messages from our C++ helper code, and pulls them out into Tracing messages.
|
||||
pub extern "C" fn libretro_log_recieve(level: LogLevel, buf: *const ffi::c_char) {
|
||||
let mut msg: Option<&str> = None;
|
||||
|
||||
// Safety: This pointer is never null, and always comes from the stack;
|
||||
// we really only should get UTF-8 errors here in the case a core spits out something invalid.
|
||||
unsafe {
|
||||
match ffi::CStr::from_ptr(buf).to_str() {
|
||||
Ok(message) => msg = Some(message),
|
||||
Ok(message) => match level {
|
||||
LogLevel::Debug => {
|
||||
debug!("{}", message)
|
||||
}
|
||||
LogLevel::Info => {
|
||||
info!("{}", message)
|
||||
}
|
||||
LogLevel::Warn => {
|
||||
warn!("{}", message)
|
||||
}
|
||||
LogLevel::Error => {
|
||||
error!("{}", message)
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
error!(
|
||||
"Core for some reason gave a broken string to log interface: {:?}",
|
||||
|
@ -21,23 +32,6 @@ pub extern "C" fn libretro_log_recieve(level: LogLevel, buf: *const ffi::c_char)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(message) = &msg {
|
||||
match level {
|
||||
LogLevel::Debug => {
|
||||
debug!("Core log: {}", message)
|
||||
}
|
||||
LogLevel::Info => {
|
||||
info!("Core log: {}", message)
|
||||
}
|
||||
LogLevel::Warn => {
|
||||
warn!("Core log: {}", message)
|
||||
}
|
||||
LogLevel::Error => {
|
||||
error!("Core log: {}", message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
|||
|
||||
use retro_frontend::{
|
||||
frontend::{Frontend, FrontendInterface},
|
||||
joypad::{Joypad, RetroPad},
|
||||
input_devices::{InputDevice, RetroPad},
|
||||
};
|
||||
use tracing::Level;
|
||||
use tracing_subscriber::FmtSubscriber;
|
||||
|
@ -25,7 +25,6 @@ impl App {
|
|||
let mut boxed = Box::new(Self {
|
||||
frontend: None,
|
||||
rfb_server: RfbServer::new(rfb_config)?,
|
||||
// nasty, but idk a better way
|
||||
pad: RetroPad::new(),
|
||||
});
|
||||
|
||||
|
@ -43,9 +42,9 @@ impl App {
|
|||
|
||||
fn init(&mut self) {
|
||||
// Currently retrovnc just hardcodes the assumption of a single RetroPad.
|
||||
let pad = &mut self.pad as *mut dyn Joypad;
|
||||
let pad = &mut self.pad as *mut dyn InputDevice;
|
||||
|
||||
self.get_frontend().set_input_port_device(0, pad);
|
||||
self.get_frontend().plug_input_device(0, pad);
|
||||
|
||||
// Initalize the display
|
||||
self.init_display();
|
||||
|
@ -66,7 +65,7 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_core<P: AsRef<Path>>(&mut self, path: P) -> Result<(), retro_frontend::result::Error> {
|
||||
fn load_core<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
|
||||
if self.get_frontend().core_loaded() {
|
||||
println!("???");
|
||||
let _ = self.get_frontend().unload_core();
|
||||
|
@ -76,7 +75,7 @@ impl App {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn load_game<P: AsRef<Path>>(&mut self, path: P) -> Result<(), retro_frontend::result::Error> {
|
||||
fn load_game<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
|
||||
self.get_frontend().load_game(path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue