more code cleanup, add a stub implementation of the mouse input device
This commit is contained in:
parent
a7544cb64d
commit
cfbbc37f8a
6 changed files with 91 additions and 17 deletions
|
@ -35,6 +35,11 @@ pub trait FrontendInterface {
|
||||||
|
|
||||||
/// Called to poll input
|
/// Called to poll input
|
||||||
fn input_poll(&mut self);
|
fn input_poll(&mut self);
|
||||||
|
|
||||||
|
// TODO(lily): Provide APIs for gathering a GL context/fbo.
|
||||||
|
// This should be abstracted so if a frontend written on top of retro_frontend
|
||||||
|
// wants to give a FBO from a GLX/WGL/windowed whatever context, it can,
|
||||||
|
// but a headless frontend can itself provide a headless EGL context just the same.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Per-core settings
|
/// Per-core settings
|
||||||
|
@ -62,11 +67,14 @@ pub struct Frontend {
|
||||||
/// Converted pixel buffer. We store it here so we don't keep allocating over and over.
|
/// Converted pixel buffer. We store it here so we don't keep allocating over and over.
|
||||||
pub(crate) converted_pixel_buffer: Vec<u32>,
|
pub(crate) converted_pixel_buffer: Vec<u32>,
|
||||||
|
|
||||||
|
// Framebuffer attributes. TODO: This really should be another struct or something
|
||||||
|
// with members to make dealing with it less annoying.
|
||||||
|
|
||||||
pub(crate) fb_width: u32,
|
pub(crate) fb_width: u32,
|
||||||
pub(crate) fb_height: u32,
|
pub(crate) fb_height: u32,
|
||||||
pub(crate) fb_pitch: u32,
|
pub(crate) fb_pitch: u32,
|
||||||
|
|
||||||
/// The "system" directory. Used for BIOS roms
|
/// The "system" directory. Used for BIOS roms.
|
||||||
pub(crate) system_directory: CString,
|
pub(crate) system_directory: CString,
|
||||||
|
|
||||||
/// The save directory. Used for saves. (TODO: Should make this per-core!!!)
|
/// The save directory. Used for saves. (TODO: Should make this per-core!!!)
|
||||||
|
@ -75,10 +83,11 @@ pub struct Frontend {
|
||||||
/// The config directory. Stores configuration for each core.
|
/// The config directory. Stores configuration for each core.
|
||||||
pub(crate) config_directory: String,
|
pub(crate) config_directory: String,
|
||||||
|
|
||||||
/// Hashmap of core variabels.
|
/// Hashmap of core variables.
|
||||||
pub(crate) variables: HashMap<String, CoreVariable>,
|
pub(crate) variables: HashMap<String, CoreVariable>,
|
||||||
|
|
||||||
pub(crate) joypads: HashMap<u32 /* port */, *mut dyn InputDevice>,
|
/// Hashmap of connected input devices.
|
||||||
|
pub(crate) input_devices: HashMap<u32 /* port */, *mut dyn InputDevice>,
|
||||||
|
|
||||||
pub(crate) interface: *mut dyn FrontendInterface,
|
pub(crate) interface: *mut dyn FrontendInterface,
|
||||||
}
|
}
|
||||||
|
@ -110,12 +119,12 @@ impl Frontend {
|
||||||
|
|
||||||
variables: HashMap::new(),
|
variables: HashMap::new(),
|
||||||
|
|
||||||
joypads: HashMap::new(),
|
input_devices: HashMap::new(),
|
||||||
|
|
||||||
interface: interface,
|
interface: interface,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assign to the global fronend pointer
|
// Assign to the global frontend pointer
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(FRONTEND.is_null(), "Cannot have multiple frontends.");
|
assert!(FRONTEND.is_null(), "Cannot have multiple frontends.");
|
||||||
FRONTEND = &mut *boxed as *mut Frontend;
|
FRONTEND = &mut *boxed as *mut Frontend;
|
||||||
|
@ -138,10 +147,10 @@ impl Frontend {
|
||||||
(core_api.retro_set_controller_port_device)(port, (*device).device_type());
|
(core_api.retro_set_controller_port_device)(port, (*device).device_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.joypads.contains_key(&port) {
|
if !self.input_devices.contains_key(&port) {
|
||||||
self.joypads.insert(port, device);
|
self.input_devices.insert(port, device);
|
||||||
} else {
|
} else {
|
||||||
(*self.joypads.get_mut(&port).unwrap()) = device;
|
(*self.input_devices.get_mut(&port).unwrap()) = device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,8 +164,8 @@ impl Frontend {
|
||||||
(core_api.retro_set_controller_port_device)(port, DEVICE_NONE);
|
(core_api.retro_set_controller_port_device)(port, DEVICE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.joypads.contains_key(&port) {
|
if !self.input_devices.contains_key(&port) {
|
||||||
self.joypads.remove(&port);
|
self.input_devices.remove(&port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +358,7 @@ impl Frontend {
|
||||||
self.fb_pitch = 0;
|
self.fb_pitch = 0;
|
||||||
|
|
||||||
// disconnect all currently connected joypads
|
// disconnect all currently connected joypads
|
||||||
self.joypads.clear();
|
self.input_devices.clear();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,21 @@
|
||||||
pub mod retropad;
|
pub mod retropad;
|
||||||
pub use retropad::*;
|
pub use retropad::*;
|
||||||
|
|
||||||
|
pub mod mouse;
|
||||||
|
pub use mouse::*;
|
||||||
|
|
||||||
/// Trait for implementing Libretro input devices
|
/// Trait for implementing Libretro input devices
|
||||||
pub trait InputDevice {
|
pub trait InputDevice {
|
||||||
// TODO: is_pressed(id: u32)?
|
/// Gets the device type. This should never EVER change, and simply return a constant.
|
||||||
|
|
||||||
fn device_type(&self) -> u32;
|
fn device_type(&self) -> u32;
|
||||||
|
|
||||||
|
/// Gets the state of one button/axis.
|
||||||
|
/// is_pressed(id) can simply be expressed as `(get_button(id) != 0)`.
|
||||||
fn get_button(&self, id: u32) -> i16;
|
fn get_button(&self, id: u32) -> i16;
|
||||||
|
|
||||||
|
/// Clears the state of all buttons/axes.
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
|
|
||||||
|
/// Presses a button/axis.
|
||||||
fn press_button(&mut self, id: u32, pressure: Option<i16>);
|
fn press_button(&mut self, id: u32, pressure: Option<i16>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
crates/retro_frontend/src/input_devices/mouse.rs
Normal file
57
crates/retro_frontend/src/input_devices/mouse.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
//! Mouse
|
||||||
|
use super::InputDevice;
|
||||||
|
use crate::libretro_sys_new;
|
||||||
|
|
||||||
|
/// Implementation of the [InputDevice] trait for the Libretro mouse.
|
||||||
|
pub struct Mouse {
|
||||||
|
buttons: [i16; 8],
|
||||||
|
|
||||||
|
// TODO: hold the last x/y so we can calculate relative position
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mouse {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { buttons: [0; 8] }
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpers:
|
||||||
|
//
|
||||||
|
// set_pos(x, y) (will do all the stupid scaling, and press the axes with the right value)
|
||||||
|
// set_buttons(mask) (will press all buttons, including wheel based on standard button mask)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputDevice for Mouse {
|
||||||
|
fn device_type(&self) -> u32 {
|
||||||
|
libretro_sys_new::DEVICE_MOUSE
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_button(&self, id: u32) -> i16 {
|
||||||
|
if id > 8 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.buttons[id as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
for button in &mut self.buttons {
|
||||||
|
*button = 0i16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn press_button(&mut self, id: u32, pressure: Option<i16>) {
|
||||||
|
if id > 8 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match pressure {
|
||||||
|
Some(pressure_value) => {
|
||||||
|
self.buttons[id as usize] = pressure_value;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// ? or 0x7fff ? Unsure
|
||||||
|
self.buttons[id as usize] = 0x7fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ impl InputDevice for RetroPad {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// ? or 0x7fff ? Unsure
|
// ? or 0x7fff ? Unsure
|
||||||
self.buttons[id as usize] = 1;
|
self.buttons[id as usize] = 0x7fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,9 +240,9 @@ pub(crate) unsafe extern "C" fn input_state_callback(
|
||||||
_index: ffi::c_uint, // not used?
|
_index: ffi::c_uint, // not used?
|
||||||
button_id: ffi::c_uint,
|
button_id: ffi::c_uint,
|
||||||
) -> ffi::c_short {
|
) -> ffi::c_short {
|
||||||
if (*FRONTEND).joypads.contains_key(&port) {
|
if (*FRONTEND).input_devices.contains_key(&port) {
|
||||||
let joypad = *(*FRONTEND)
|
let joypad = *(*FRONTEND)
|
||||||
.joypads
|
.input_devices
|
||||||
.get(&port)
|
.get(&port)
|
||||||
.expect("How do we get here when contains_key() returns true but the key doen't exist");
|
.expect("How do we get here when contains_key() returns true but the key doen't exist");
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,9 @@ impl RfbServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Pull this out of here, and instead do it in retrovnc app proper.
|
||||||
|
// This will also make the rfb code more generic which is always a good thing
|
||||||
|
|
||||||
pub fn get_buttons(&self) -> [bool; 32] {
|
pub fn get_buttons(&self) -> [bool; 32] {
|
||||||
self.buttons
|
self.buttons
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue