ferretro/src/libretro_convert.rs

238 lines
9.3 KiB
Rust
Raw Normal View History

use std::convert::{TryFrom, TryInto};
use std::os::raw::c_uint;
use std::path::PathBuf;
use num_enum::{TryFromPrimitive, IntoPrimitive};
use crate::libretro_ffi::*;
// NB: commented-out stuff is from newer versions of libretro.h not yet represented in libretro-sys
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum DeviceType {
None = DEVICE_NONE,
Joypad = DEVICE_JOYPAD,
Mouse = DEVICE_MOUSE,
Keyboard = DEVICE_KEYBOARD,
LightGun = DEVICE_LIGHTGUN,
Analog = DEVICE_ANALOG,
Pointer = DEVICE_POINTER,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum DeviceIndex {
Left = DEVICE_INDEX_ANALOG_LEFT,
Right = DEVICE_INDEX_ANALOG_RIGHT,
// Button = DEVICE_INDEX_ANALOG_BUTTON,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum JoypadButton {
B = DEVICE_ID_JOYPAD_B,
Y = DEVICE_ID_JOYPAD_Y,
Select = DEVICE_ID_JOYPAD_SELECT,
Start = DEVICE_ID_JOYPAD_START,
Up = DEVICE_ID_JOYPAD_UP,
Down = DEVICE_ID_JOYPAD_DOWN,
Left = DEVICE_ID_JOYPAD_LEFT,
Right = DEVICE_ID_JOYPAD_RIGHT,
A = DEVICE_ID_JOYPAD_A,
X = DEVICE_ID_JOYPAD_X,
L = DEVICE_ID_JOYPAD_L,
R = DEVICE_ID_JOYPAD_R,
L2 = DEVICE_ID_JOYPAD_L2,
R2 = DEVICE_ID_JOYPAD_R2,
L3 = DEVICE_ID_JOYPAD_L3,
R3 = DEVICE_ID_JOYPAD_R3,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum AnalogAxis {
X = DEVICE_ID_ANALOG_X,
Y = DEVICE_ID_ANALOG_Y,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum MouseButton {
X = DEVICE_ID_MOUSE_X,
Y = DEVICE_ID_MOUSE_Y,
Left = DEVICE_ID_MOUSE_LEFT,
Right = DEVICE_ID_MOUSE_RIGHT,
WheelUp = DEVICE_ID_MOUSE_WHEELUP,
WheelDown = DEVICE_ID_MOUSE_WHEELDOWN,
Middle = DEVICE_ID_MOUSE_MIDDLE,
HorizWheelUp = DEVICE_ID_MOUSE_HORIZ_WHEELUP,
HorizWheelDown = DEVICE_ID_MOUSE_HORIZ_WHEELDOWN,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum LightGunButton {
// ScreenX = DEVICE_ID_LIGHTGUN_SCREEN_X,
// ScreenY = DEVICE_ID_LIGHTGUN_SCREEN_Y,
// IsOffscreen = DEVICE_ID_LIGHTGUN_IS_OFFSCREEN,
Trigger = DEVICE_ID_LIGHTGUN_TRIGGER,
// Reload = DEVICE_ID_LIGHTGUN_RELOAD,
Start = DEVICE_ID_LIGHTGUN_START,
// Select = DEVICE_ID_LIGHTGUN_SELECT,
// AuxC = DEVICE_ID_LIGHTGUN_AUX_C,
// DpadUp = DEVICE_ID_LIGHTGUN_DPAD_UP,
// DpadDown = DEVICE_ID_LIGHTGUN_DPAD_DOWN,
// DpadLeft = DEVICE_ID_LIGHTGUN_DPAD_LEFT,
// DpadRight = DEVICE_ID_LIGHTGUN_DPAD_RIGHT,
X = DEVICE_ID_LIGHTGUN_X,
Y = DEVICE_ID_LIGHTGUN_Y,
Cursor = DEVICE_ID_LIGHTGUN_CURSOR,
Turbo = DEVICE_ID_LIGHTGUN_TURBO,
Pause = DEVICE_ID_LIGHTGUN_PAUSE,
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum PointerStat {
X = DEVICE_ID_POINTER_X,
Y = DEVICE_ID_POINTER_Y,
Pressed = DEVICE_ID_POINTER_PRESSED,
}
pub enum Input {
None(c_uint),
Joypad(JoypadButton),
Mouse(MouseButton),
Keyboard(c_uint),
LightGun(LightGunButton),
Analog(AnalogAxis),
Pointer(PointerStat),
}
impl<D> TryFrom<(D, c_uint)> for Input
where D: TryInto<DeviceType>,
<D as std::convert::TryInto<DeviceType>>::Error: std::error::Error + Send + Sync + 'static,
{
type Error = failure::Error;
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)?),
})
}
}
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum EnvRotation {
None = 0,
CounterClockwise90 = 1,
CounterClockwise180 = 2,
CounterClockwise270 = 3,
}
pub struct EnvVariable {
key: &'static str,
description: &'static str,
expected_values: Vec<&'static str>,
value: Option<String>,
}
// TODO: experimental calls
#[derive(TryFromPrimitive, IntoPrimitive)]
#[repr(u32)]
pub enum EnvCmd {
SetRotation = ENVIRONMENT_SET_ROTATION,
GetOverscan = ENVIRONMENT_GET_OVERSCAN,
GetCanDupe = ENVIRONMENT_GET_CAN_DUPE,
SetMessage = ENVIRONMENT_SET_MESSAGE,
Shutdown = ENVIRONMENT_SHUTDOWN,
SetPerformanceLevel = ENVIRONMENT_SET_PERFORMANCE_LEVEL,
GetSystemDirectory = ENVIRONMENT_GET_SYSTEM_DIRECTORY,
SetPixelFormat = ENVIRONMENT_SET_PIXEL_FORMAT,
SetInputDescriptors = ENVIRONMENT_SET_INPUT_DESCRIPTORS,
SetKeyboardCallback = ENVIRONMENT_SET_KEYBOARD_CALLBACK,
SetDiskControlInterface = ENVIRONMENT_SET_DISK_CONTROL_INTERFACE,
SetHwRender = ENVIRONMENT_SET_HW_RENDER,
GetVariable = ENVIRONMENT_GET_VARIABLE,
SetVariables = ENVIRONMENT_SET_VARIABLES,
GetVariableUpdate = ENVIRONMENT_GET_VARIABLE_UPDATE,
SetSupportNoGame = ENVIRONMENT_SET_SUPPORT_NO_GAME,
GetLibretroPath = ENVIRONMENT_GET_LIBRETRO_PATH,
SetFrameTimeCallback = ENVIRONMENT_SET_FRAME_TIME_CALLBACK,
SetAudioCallback = ENVIRONMENT_SET_AUDIO_CALLBACK,
GetRumbleInterface = ENVIRONMENT_GET_RUMBLE_INTERFACE,
GetInputDeviceCapabilities = ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES,
GetSensorInterface = ENVIRONMENT_GET_SENSOR_INTERFACE,
GetCameraInterface = ENVIRONMENT_GET_CAMERA_INTERFACE,
GetLogInterface = ENVIRONMENT_GET_LOG_INTERFACE,
GetPerfInterface = ENVIRONMENT_GET_PERF_INTERFACE,
GetLocationInterface = ENVIRONMENT_GET_LOCATION_INTERFACE,
GetCoreAssetsDirectory = ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY,
GetSaveDirectory = ENVIRONMENT_GET_SAVE_DIRECTORY,
SetSystemAvInfo = ENVIRONMENT_SET_SYSTEM_AV_INFO,
SetProcAddressCallback = ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK,
SetSubsystemInfo = ENVIRONMENT_SET_SUBSYSTEM_INFO,
SetControllerInfo = ENVIRONMENT_SET_CONTROLLER_INFO,
SetMemoryMaps = ENVIRONMENT_SET_MEMORY_MAPS,
SetGeometry = ENVIRONMENT_SET_GEOMETRY,
GetUsername = ENVIRONMENT_GET_USERNAME,
GetLanguage = ENVIRONMENT_GET_LANGUAGE,
// SetSerializationQuirks = ENVIRONMENT_SET_SERIALIZATION_QUIRKS,
}
pub trait Handler: Send + Sync + 'static {
fn video_refresh(&mut self, data: &[u8], width: c_uint, height: c_uint, pitch: c_uint) {}
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 }
// -- environment callbacks --
fn set_rotation(&mut self, rotation: EnvRotation) -> bool { false }
fn get_overscan(&mut self) -> Option<bool> { None }
fn get_can_dupe(&mut self) -> Option<bool> { None }
fn set_message(&mut self, message: Message) -> bool { false }
fn shutdown(&mut self) -> bool { false }
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_keyboard_callback(&mut self, cb: KeyboardCallback) -> bool { false }
fn set_disk_control_interface(&mut self, cb: DiskControlCallback) -> bool { false }
fn set_hw_render(&mut self, hw_render_callback: HwRenderCallback) -> bool { false }
fn get_variable(&mut self) -> Option<EnvVariable> { None }
fn set_variables(&mut self, variables: &[EnvVariable]) -> 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 }
fn set_frame_time_callback(&mut self, cb: FrameTimeCallback) -> bool { false }
fn set_audio_callback(&mut self, audio_callback: AudioCallback) -> bool { false }
fn get_rumble_interface(&mut self) -> Option<RumbleInterface> { None }
fn get_input_device_capabilities(&mut self) -> Option<u64> { None }
fn get_sensor_interface(&mut self) -> Option<SensorInterface> { None }
fn get_camera_interface(&mut self) -> Option<CameraCallback> { None }
fn get_log_interface(&mut self) -> Option<LogCallback> { None }
fn get_perf_interface(&mut self) -> Option<PerfCallback> { None }
fn get_location_interface(&mut self) -> Option<LocationCallback> { None }
fn get_core_assets_directory(&mut self) -> Option<PathBuf> { None }
fn get_save_directory(&mut self) -> Option<PathBuf> { None }
fn set_system_av_info(&mut self, system_av_info: SystemAvInfo) -> bool { false }
fn set_proc_address_callback(&mut self, cb: GetProcAddressInterface) -> bool { false }
fn set_subsystem_info(&mut self, subsystem_info: SubsystemInfo) -> bool { false }
fn set_controller_info(&mut self, controller_info: ControllerInfo) -> bool { false }
fn set_memory_maps(&mut self, memory_map: MemoryMap) -> bool { false }
fn set_geometry(&mut self, game_geometry: GameGeometry) -> bool { false }
fn get_username(&mut self) -> Option<String> { None }
fn get_language(&mut self) -> Option<Language> { None }
// fn set_serialization_quirks(&mut self, quirks: &mut u64) -> bool { false }
}