implement ENVIRONMENT_SET_INPUT_DESCRIPTORS
This commit is contained in:
parent
49aa491904
commit
3f31cf6625
|
@ -4,8 +4,8 @@ extern crate sdl2;
|
|||
|
||||
use rustro::retro;
|
||||
use rustro::retro::ffi::{GameGeometry, SystemInfo, SystemAvInfo};
|
||||
use rustro::retro::constants::{Input, DeviceIndex, JoypadButton, AnalogAxis, DeviceType};
|
||||
use rustro::retro::wrapper::{LibretroWrapper, VariableDescriptor, ControllerDescription2, SubsystemInfo2};
|
||||
use rustro::retro::constants::{InputDeviceId, InputIndex, JoypadButton, AnalogAxis, DeviceType};
|
||||
use rustro::retro::wrapper::{LibretroWrapper, Variable2, ControllerDescription2, SubsystemInfo2, InputDescriptor2};
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::io::Read;
|
||||
|
@ -239,11 +239,11 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
self.gamepad_subsys.update();
|
||||
}
|
||||
|
||||
fn input_state(&mut self, port: u32, device: Input, index: DeviceIndex) -> i16 {
|
||||
fn input_state(&mut self, port: u32, device: InputDeviceId, index: InputIndex) -> i16 {
|
||||
match self.gamepads.get(port as usize) {
|
||||
Some(gamepad) => {
|
||||
match device {
|
||||
Input::Joypad(button) => {
|
||||
InputDeviceId::Joypad(button) => {
|
||||
match button_map(&button) {
|
||||
Some(x) => gamepad.button(x) as i16,
|
||||
None => match button {
|
||||
|
@ -253,7 +253,7 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
}
|
||||
}
|
||||
}
|
||||
Input::Analog(axis) => gamepad.axis(axis_map(index, axis)),
|
||||
InputDeviceId::Analog(axis) => gamepad.axis(axis_map(index, axis)),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
@ -275,11 +275,6 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
};
|
||||
true
|
||||
}
|
||||
fn set_subsystem_info(&mut self, subsystem_info: Vec<SubsystemInfo2>) -> bool {
|
||||
println!("subsystem info: {:?}", subsystem_info);
|
||||
true
|
||||
}
|
||||
|
||||
fn get_variable(&mut self, key: &str) -> Option<String> {
|
||||
match key {
|
||||
"beetle_saturn_analog_stick_deadzone" => Some("15%".to_string()),
|
||||
|
@ -289,7 +284,7 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_variables(&mut self, variables: Vec<VariableDescriptor>) -> bool {
|
||||
fn set_variables(&mut self, variables: Vec<Variable2>) -> bool {
|
||||
for v in variables {
|
||||
eprintln!("{:?}", v);
|
||||
}
|
||||
|
@ -315,6 +310,11 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
true
|
||||
}
|
||||
|
||||
fn set_subsystem_info(&mut self, subsystem_info: Vec<SubsystemInfo2>) -> bool {
|
||||
println!("subsystem info: {:?}", subsystem_info);
|
||||
true
|
||||
}
|
||||
|
||||
fn set_controller_info(&mut self, controller_info: Vec<ControllerDescription2>) -> bool {
|
||||
for ci in controller_info {
|
||||
// so we can have analog support in beetle/mednafen saturn
|
||||
|
@ -326,6 +326,13 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
true
|
||||
}
|
||||
|
||||
fn set_input_descriptors(&mut self, descriptors: Vec<InputDescriptor2>) -> bool {
|
||||
for id in descriptors {
|
||||
println!("{:?}", id);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn set_geometry(&mut self, geom: GameGeometry) -> bool {
|
||||
let _ = self.canvas.window_mut().set_size(geom.base_width, geom.base_height);
|
||||
let _ = self.canvas.set_logical_size(geom.base_width, geom.base_height);
|
||||
|
@ -399,11 +406,11 @@ fn button_map(retro_button: &JoypadButton) -> Option<Button> {
|
|||
}
|
||||
}
|
||||
|
||||
fn axis_map(index: DeviceIndex, axis: AnalogAxis) -> Axis {
|
||||
fn axis_map(index: InputIndex, axis: AnalogAxis) -> Axis {
|
||||
match (index, axis) {
|
||||
(DeviceIndex::Left, AnalogAxis::X) => Axis::LeftX,
|
||||
(DeviceIndex::Left, AnalogAxis::Y) => Axis::LeftY,
|
||||
(DeviceIndex::Right, AnalogAxis::X) => Axis::RightX,
|
||||
(DeviceIndex::Right, AnalogAxis::Y) => Axis::RightY,
|
||||
(InputIndex::Left, AnalogAxis::X) => Axis::LeftX,
|
||||
(InputIndex::Left, AnalogAxis::Y) => Axis::LeftY,
|
||||
(InputIndex::Right, AnalogAxis::X) => Axis::RightX,
|
||||
(InputIndex::Right, AnalogAxis::Y) => Axis::RightY,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ impl DeviceType {
|
|||
|
||||
#[derive(TryFromPrimitive, IntoPrimitive, Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum DeviceIndex {
|
||||
pub enum InputIndex {
|
||||
Left = DEVICE_INDEX_ANALOG_LEFT,
|
||||
Right = DEVICE_INDEX_ANALOG_RIGHT,
|
||||
// Button = DEVICE_INDEX_ANALOG_BUTTON,
|
||||
|
@ -106,7 +106,7 @@ pub enum PointerStat {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Input {
|
||||
pub enum InputDeviceId {
|
||||
None(c_uint),
|
||||
Joypad(JoypadButton),
|
||||
Mouse(MouseButton),
|
||||
|
@ -116,7 +116,7 @@ pub enum Input {
|
|||
Pointer(PointerStat),
|
||||
}
|
||||
|
||||
impl<D> TryFrom<(D, c_uint)> for Input
|
||||
impl<D> TryFrom<(D, c_uint)> for InputDeviceId
|
||||
where D: TryInto<DeviceType>,
|
||||
<D as std::convert::TryInto<DeviceType>>::Error: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
|
@ -125,13 +125,13 @@ impl<D> TryFrom<(D, c_uint)> for Input
|
|||
fn try_from(pair: (D, c_uint)) -> failure::Fallible<Self> {
|
||||
let (device, id) = pair;
|
||||
Ok(match device.try_into()? {
|
||||
DeviceType::None => Input::None(id),
|
||||
DeviceType::Joypad => Input::Joypad(JoypadButton::try_from(id)?),
|
||||
DeviceType::Mouse => Input::Mouse(MouseButton::try_from(id)?),
|
||||
DeviceType::Keyboard => Input::Keyboard(id),
|
||||
DeviceType::LightGun => Input::LightGun(LightGunButton::try_from(id)?),
|
||||
DeviceType::Analog => Input::Analog(AnalogAxis::try_from(id)?),
|
||||
DeviceType::Pointer => Input::Pointer(PointerStat::try_from(id)?),
|
||||
DeviceType::None => InputDeviceId::None(id),
|
||||
DeviceType::Joypad => InputDeviceId::Joypad(JoypadButton::try_from(id)?),
|
||||
DeviceType::Mouse => InputDeviceId::Mouse(MouseButton::try_from(id)?),
|
||||
DeviceType::Keyboard => InputDeviceId::Keyboard(id),
|
||||
DeviceType::LightGun => InputDeviceId::LightGun(LightGunButton::try_from(id)?),
|
||||
DeviceType::Analog => InputDeviceId::Analog(AnalogAxis::try_from(id)?),
|
||||
DeviceType::Pointer => InputDeviceId::Pointer(PointerStat::try_from(id)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ pub trait Handler: Unpin + 'static {
|
|||
fn audio_sample(&mut self, left: i16, right: i16) {}
|
||||
fn audio_sample_batch(&mut self, stereo_pcm: &[i16]) -> usize { stereo_pcm.len() }
|
||||
fn input_poll(&mut self) {}
|
||||
fn input_state(&mut self, port: u32, device: Input, index: DeviceIndex) -> i16 { 0 }
|
||||
fn input_state(&mut self, port: u32, device: InputDeviceId, index: InputIndex) -> i16 { 0 }
|
||||
|
||||
// -- environment callbacks --
|
||||
fn set_rotation(&mut self, rotation: EnvRotation) -> bool { false }
|
||||
|
@ -49,10 +49,10 @@ pub trait Handler: Unpin + 'static {
|
|||
fn set_performance_level(&mut self, level: c_uint) -> bool { false }
|
||||
fn get_system_directory(&mut self) -> Option<PathBuf> { None }
|
||||
fn set_pixel_format(&mut self, format: PixelFormat) -> bool { false }
|
||||
fn set_input_descriptors(&mut self, input_descriptors: &[InputDescriptor]) -> bool { false }
|
||||
fn set_input_descriptors(&mut self, input_descriptors: Vec<InputDescriptor2>) -> bool { false }
|
||||
fn set_hw_render(&mut self, hw_render_callback: HwRenderCallback) -> bool { false }
|
||||
fn get_variable(&mut self, key: &str) -> Option<String> { None }
|
||||
fn set_variables(&mut self, variables: Vec<VariableDescriptor>) -> bool { false }
|
||||
fn set_variables(&mut self, variables: Vec<Variable2>) -> bool { false }
|
||||
fn get_variable_update(&mut self) -> Option<bool> { None }
|
||||
fn set_support_no_game(&mut self, supports_no_game: bool) -> bool { false }
|
||||
fn get_libretro_path(&mut self) -> Option<PathBuf> { None }
|
||||
|
@ -80,13 +80,13 @@ pub trait Handler: Unpin + 'static {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableDescriptor {
|
||||
pub struct Variable2 {
|
||||
pub key: String,
|
||||
pub description: String,
|
||||
pub options: Vec<String>,
|
||||
}
|
||||
|
||||
impl From<&Variable> for VariableDescriptor {
|
||||
impl From<&Variable> for Variable2 {
|
||||
fn from(var: &Variable) -> Self {
|
||||
let key = unsafe { CStr::from_ptr(var.key) }
|
||||
.to_string_lossy()
|
||||
|
@ -102,7 +102,7 @@ impl From<&Variable> for VariableDescriptor {
|
|||
.split('|')
|
||||
.map(String::from)
|
||||
.collect();
|
||||
VariableDescriptor {
|
||||
Variable2 {
|
||||
key,
|
||||
description,
|
||||
options,
|
||||
|
@ -146,6 +146,33 @@ impl TryFrom<&ControllerDescription> for ControllerDescription2 {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InputDescriptor2 {
|
||||
pub port: c_uint,
|
||||
pub device_id: InputDeviceId,
|
||||
pub index: InputIndex,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
impl TryFrom<&InputDescriptor> for InputDescriptor2 {
|
||||
type Error = ();
|
||||
fn try_from(t: &InputDescriptor) -> Result<Self, Self::Error> {
|
||||
if t.id >> DEVICE_TYPE_SHIFT != 0 {
|
||||
eprintln!("Device subclass encountered in retro_input_descriptor, ignoring");
|
||||
}
|
||||
let description = unsafe { CStr::from_ptr(t.description) }
|
||||
.to_str()
|
||||
.map_err(|_| ())?
|
||||
.to_string();
|
||||
Ok(InputDescriptor2 {
|
||||
port: t.port,
|
||||
device_id: InputDeviceId::try_from((t.device & DEVICE_MASK, t.id)).map_err(|_| ())?,
|
||||
index: InputIndex::try_from(t.index).map_err(|_| ())?,
|
||||
description,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SubsystemInfo2 {
|
||||
pub description: String,
|
||||
|
@ -286,7 +313,15 @@ impl StaticCallbacks {
|
|||
EnvCmd::SetPixelFormat => {
|
||||
handler.set_pixel_format(PixelFormat::from_uint(*Self::from_void(data)?)?)
|
||||
}
|
||||
// TODO EnvCmd::SetInputDescriptors => {},
|
||||
EnvCmd::SetInputDescriptors => {
|
||||
let mut input_desc = data as *const InputDescriptor;
|
||||
let mut descriptors = Vec::new();
|
||||
while !unsafe { input_desc.as_ref() }?.description.is_null() {
|
||||
descriptors.push(unsafe { input_desc.as_ref() }?.try_into().ok()?);
|
||||
input_desc = input_desc.wrapping_add(1);
|
||||
}
|
||||
handler.set_input_descriptors(descriptors)
|
||||
},
|
||||
EnvCmd::SetKeyboardCallback => {
|
||||
let kc: &mut KeyboardCallback = Self::from_void(data)?;
|
||||
handler
|
||||
|
|
Loading…
Reference in New Issue