start making giant match statement in environment cb wrapper
This commit is contained in:
parent
eaab387216
commit
498c874bc7
|
@ -1,19 +1,19 @@
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::os::raw::{c_uint, c_void};
|
use std::os::raw::c_uint;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::{TryFromPrimitive, IntoPrimitive};
|
||||||
|
|
||||||
use crate::libretro_ffi::*;
|
use crate::libretro_ffi::*;
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum Region {
|
pub enum Region {
|
||||||
NTSC = RETRO_REGION_NTSC,
|
NTSC = RETRO_REGION_NTSC,
|
||||||
PAL = RETRO_REGION_PAL,
|
PAL = RETRO_REGION_PAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum DeviceType {
|
pub enum DeviceType {
|
||||||
None = RETRO_DEVICE_NONE,
|
None = RETRO_DEVICE_NONE,
|
||||||
|
@ -25,7 +25,7 @@ pub enum DeviceType {
|
||||||
Pointer = RETRO_DEVICE_POINTER,
|
Pointer = RETRO_DEVICE_POINTER,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum DeviceIndex {
|
pub enum DeviceIndex {
|
||||||
Left = RETRO_DEVICE_INDEX_ANALOG_LEFT,
|
Left = RETRO_DEVICE_INDEX_ANALOG_LEFT,
|
||||||
|
@ -33,7 +33,7 @@ pub enum DeviceIndex {
|
||||||
Button = RETRO_DEVICE_INDEX_ANALOG_BUTTON,
|
Button = RETRO_DEVICE_INDEX_ANALOG_BUTTON,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum JoypadButton {
|
pub enum JoypadButton {
|
||||||
B = RETRO_DEVICE_ID_JOYPAD_B,
|
B = RETRO_DEVICE_ID_JOYPAD_B,
|
||||||
|
@ -54,14 +54,14 @@ pub enum JoypadButton {
|
||||||
R3 = RETRO_DEVICE_ID_JOYPAD_R3,
|
R3 = RETRO_DEVICE_ID_JOYPAD_R3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum AnalogAxis {
|
pub enum AnalogAxis {
|
||||||
X = RETRO_DEVICE_ID_ANALOG_X,
|
X = RETRO_DEVICE_ID_ANALOG_X,
|
||||||
Y = RETRO_DEVICE_ID_ANALOG_Y,
|
Y = RETRO_DEVICE_ID_ANALOG_Y,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum MouseButton {
|
pub enum MouseButton {
|
||||||
X = RETRO_DEVICE_ID_MOUSE_X,
|
X = RETRO_DEVICE_ID_MOUSE_X,
|
||||||
|
@ -77,7 +77,7 @@ pub enum MouseButton {
|
||||||
Button5 = RETRO_DEVICE_ID_MOUSE_BUTTON_5,
|
Button5 = RETRO_DEVICE_ID_MOUSE_BUTTON_5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum LightGunButton {
|
pub enum LightGunButton {
|
||||||
ScreenX = RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X,
|
ScreenX = RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X,
|
||||||
|
@ -99,7 +99,7 @@ pub enum LightGunButton {
|
||||||
Pause = RETRO_DEVICE_ID_LIGHTGUN_PAUSE,
|
Pause = RETRO_DEVICE_ID_LIGHTGUN_PAUSE,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum PointerStat {
|
pub enum PointerStat {
|
||||||
X = RETRO_DEVICE_ID_POINTER_X,
|
X = RETRO_DEVICE_ID_POINTER_X,
|
||||||
|
@ -137,7 +137,7 @@ impl<D> TryFrom<(D, c_uint)> for Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum EnvRotation {
|
pub enum EnvRotation {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -146,7 +146,7 @@ pub enum EnvRotation {
|
||||||
CounterClockwise270 = 3,
|
CounterClockwise270 = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum EnvPixelFormat {
|
pub enum EnvPixelFormat {
|
||||||
XRGB555 = retro_pixel_format_RETRO_PIXEL_FORMAT_0RGB1555,
|
XRGB555 = retro_pixel_format_RETRO_PIXEL_FORMAT_0RGB1555,
|
||||||
|
@ -162,7 +162,7 @@ pub struct EnvVariable {
|
||||||
value: Option<String>,
|
value: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum EnvLanguage {
|
pub enum EnvLanguage {
|
||||||
English = retro_language_RETRO_LANGUAGE_ENGLISH,
|
English = retro_language_RETRO_LANGUAGE_ENGLISH,
|
||||||
|
@ -186,90 +186,89 @@ pub enum EnvLanguage {
|
||||||
Last = retro_language_RETRO_LANGUAGE_LAST,
|
Last = retro_language_RETRO_LANGUAGE_LAST,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: lifetime
|
|
||||||
// TODO: experimental calls
|
// TODO: experimental calls
|
||||||
|
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||||
|
#[repr(u32)]
|
||||||
pub enum EnvironmentCmdData {
|
pub enum EnvironmentCmdData {
|
||||||
SetRotation(EnvRotation),
|
SetRotation = RETRO_ENVIRONMENT_SET_ROTATION,
|
||||||
GetOverscan(&'static mut bool),
|
GetOverscan = RETRO_ENVIRONMENT_GET_OVERSCAN,
|
||||||
GetCanDupe(&'static mut bool),
|
GetCanDupe = RETRO_ENVIRONMENT_GET_CAN_DUPE,
|
||||||
SetMessage(retro_message), // TODO
|
SetMessage = RETRO_ENVIRONMENT_SET_MESSAGE,
|
||||||
Shutdown,
|
Shutdown = RETRO_ENVIRONMENT_SHUTDOWN,
|
||||||
SetPerformanceLevel(c_uint),
|
SetPerformanceLevel = RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL,
|
||||||
GetSystemDirectory(&'static mut PathBuf),
|
GetSystemDirectory = RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY,
|
||||||
SetPixelFormat(EnvPixelFormat),
|
SetPixelFormat = RETRO_ENVIRONMENT_SET_PIXEL_FORMAT,
|
||||||
SetInputDescriptors(&'static [retro_input_descriptor]), // TODO
|
SetInputDescriptors = RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS,
|
||||||
SetKeyboardCallback(retro_keyboard_callback), // TODO
|
SetKeyboardCallback = RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK,
|
||||||
SetDiskControlInterface(retro_disk_control_callback), // TODO
|
SetDiskControlInterface = RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE,
|
||||||
SetHwRender(retro_hw_render_callback), // TODO
|
SetHwRender = RETRO_ENVIRONMENT_SET_HW_RENDER,
|
||||||
GetVariable(&'static mut EnvVariable),
|
GetVariable = RETRO_ENVIRONMENT_GET_VARIABLE,
|
||||||
SetVariables(&'static [EnvVariable]),
|
SetVariables = RETRO_ENVIRONMENT_SET_VARIABLES,
|
||||||
GetVariableUpdate(&'static mut bool),
|
GetVariableUpdate = RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE,
|
||||||
SetSupportNoGame(bool),
|
SetSupportNoGame = RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME,
|
||||||
GetLibretroPath(&'static mut PathBuf),
|
GetLibretroPath = RETRO_ENVIRONMENT_GET_LIBRETRO_PATH,
|
||||||
SetFrameTimeCallback(retro_frame_time_callback), // TODO
|
SetFrameTimeCallback = RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK,
|
||||||
SetAudioCallback(retro_audio_callback), // TODO
|
SetAudioCallback = RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK,
|
||||||
GetRumbleInterface(&'static mut retro_rumble_interface), // TODO
|
GetRumbleInterface = RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE,
|
||||||
GetInputDeviceCapabilities(&'static mut u64), // TODO
|
GetInputDeviceCapabilities = RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES,
|
||||||
GetSensorInterface(&'static mut retro_sensor_interface), // TODO
|
GetSensorInterface = RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE,
|
||||||
GetCameraInterface(&'static mut retro_camera_callback), // TODO
|
GetCameraInterface = RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE,
|
||||||
GetLogInterface(&'static mut retro_log_callback), // TODO
|
GetLogInterface = RETRO_ENVIRONMENT_GET_LOG_INTERFACE,
|
||||||
GetPerfInterface(&'static mut retro_perf_callback), // TODO
|
GetPerfInterface = RETRO_ENVIRONMENT_GET_PERF_INTERFACE,
|
||||||
GetLocationInterface(&'static mut retro_location_callback), // TODO
|
GetLocationInterface = RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE,
|
||||||
GetCoreAssetsDirectory(&'static mut PathBuf),
|
GetCoreAssetsDirectory = RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY,
|
||||||
GetSaveDirectory(&'static mut PathBuf),
|
GetSaveDirectory = RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY,
|
||||||
SetSystemAvInfo(retro_system_av_info),
|
SetSystemAvInfo = RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO,
|
||||||
SetProcAddressCallback(retro_get_proc_address_interface), // TODO
|
SetProcAddressCallback = RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK,
|
||||||
SetSubsystemInfo(retro_subsystem_info), // TODO
|
SetSubsystemInfo = RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO,
|
||||||
SetControllerInfo(retro_controller_info), // TODO
|
SetControllerInfo = RETRO_ENVIRONMENT_SET_CONTROLLER_INFO,
|
||||||
SetMemoryMaps(retro_memory_map), // TODO
|
SetMemoryMaps = RETRO_ENVIRONMENT_SET_MEMORY_MAPS,
|
||||||
SetGeometry(retro_game_geometry), // TODO
|
SetGeometry = RETRO_ENVIRONMENT_SET_GEOMETRY,
|
||||||
GetUsername(&'static mut String),
|
GetUsername = RETRO_ENVIRONMENT_GET_USERNAME,
|
||||||
GetLanguage(&'static mut EnvLanguage),
|
GetLanguage = RETRO_ENVIRONMENT_GET_LANGUAGE,
|
||||||
SetSerializationQuirks(&'static mut u64), // TODO
|
SetSerializationQuirks = RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HandlesEnvironment: Send + Sync + 'static {
|
pub trait HandlesEnvironment: Send + Sync + 'static {
|
||||||
// TODO: wrap cmd+data in enum
|
fn set_rotation(&mut self, rotation: EnvRotation) -> bool { false }
|
||||||
fn environment(&mut self, cmd: u32, data: *mut c_void) -> bool;
|
fn get_overscan(&mut self) -> Option<bool> { None }
|
||||||
|
fn get_can_dupe(&mut self) -> Option<bool> { None }
|
||||||
fn SetRotation(&mut self, rotation: EnvRotation) -> bool;
|
fn set_message(&mut self, message: retro_message) -> bool { false }
|
||||||
fn GetOverscan(&mut self, overscan: &mut bool) -> bool;
|
fn shutdown(&mut self) -> bool { false }
|
||||||
fn GetCanDupe(&mut self, frame_duping: &mut bool) -> bool;
|
fn set_performance_level(&mut self, level: c_uint) -> bool { false }
|
||||||
fn SetMessage(&mut self, message: retro_message) -> bool;
|
fn get_system_directory(&mut self) -> Option<PathBuf> { None }
|
||||||
fn Shutdown(&mut self) -> bool;
|
fn set_pixel_format(&mut self, format: EnvPixelFormat) -> bool { false }
|
||||||
fn SetPerformanceLevel(&mut self, level: c_uint) -> bool;
|
fn set_input_descriptors(&mut self, input_descriptors: &[retro_input_descriptor]) -> bool { false }
|
||||||
fn GetSystemDirectory(&mut self, path: &mut PathBuf) -> bool;
|
fn set_keyboard_callback(&mut self, cb: retro_keyboard_callback) -> bool { false }
|
||||||
fn SetPixelFormat(&mut self, format: EnvPixelFormat) -> bool;
|
fn set_disk_control_interface(&mut self, cb: retro_disk_control_callback) -> bool { false }
|
||||||
fn SetInputDescriptors(&mut self, input_descriptors: &[retro_input_descriptor]) -> bool;
|
fn set_hw_render(&mut self, hw_render_callback: retro_hw_render_callback) -> bool { false }
|
||||||
fn SetKeyboardCallback(&mut self, keyboard_callback: retro_keyboard_callback) -> bool;
|
fn get_variable(&mut self) -> Option<EnvVariable> { None }
|
||||||
fn SetDiskControlInterface(&mut self, disk_control_callback: retro_disk_control_callback) -> bool;
|
fn set_variables(&mut self, variables: &[EnvVariable]) -> bool { false }
|
||||||
fn SetHwRender(&mut self, hw_render_callback: retro_hw_render_callback) -> bool;
|
fn get_variable_update(&mut self) -> Option<bool> { None }
|
||||||
fn GetVariable(&mut self, variable: &mut EnvVariable) -> bool;
|
fn set_support_no_game(&mut self, supports_no_game: bool) -> bool { false }
|
||||||
fn SetVariables(&mut self, variables: &[EnvVariable]) -> bool;
|
fn get_libretro_path(&mut self) -> Option<PathBuf> { None }
|
||||||
fn GetVariableUpdate(&mut self, variables_updated: &mut bool) -> bool;
|
fn set_frame_time_callback(&mut self, cb: retro_frame_time_callback) -> bool { false }
|
||||||
fn SetSupportNoGame(&mut self, supports_no_game: bool) -> bool;
|
fn set_audio_callback(&mut self, audio_callback: retro_audio_callback) -> bool { false }
|
||||||
fn GetLibretroPath(&mut self, path: &mut PathBuf) -> bool;
|
fn get_rumble_interface(&mut self) -> Option<retro_rumble_interface> { None }
|
||||||
fn SetFrameTimeCallback(&mut self, frame_time_callback: retro_frame_time_callback) -> bool;
|
fn get_input_device_capabilities(&mut self) -> Option<u64> { None }
|
||||||
fn SetAudioCallback(&mut self, audio_callback: retro_audio_callback) -> bool;
|
fn get_sensor_interface(&mut self) -> Option<retro_sensor_interface> { None }
|
||||||
fn GetRumbleInterface(&mut self, rumble_interface: &mut retro_rumble_interface) -> bool;
|
fn get_camera_interface(&mut self) -> Option<retro_camera_callback> { None }
|
||||||
fn GetInputDeviceCapabilities(&mut self, input_device_capabilities: &mut u64) -> bool;
|
fn get_log_interface(&mut self) -> Option<retro_log_callback> { None }
|
||||||
fn GetSensorInterface(&mut self, sensor_interface: &mut retro_sensor_interface) -> bool;
|
fn get_perf_interface(&mut self) -> Option<retro_perf_callback> { None }
|
||||||
fn GetCameraInterface(&mut self, camera_callback: &mut retro_camera_callback) -> bool;
|
fn get_location_interface(&mut self) -> Option<retro_location_callback> { None }
|
||||||
fn GetLogInterface(&mut self, log_callback: &mut retro_log_callback) -> bool;
|
fn get_core_assets_directory(&mut self) -> Option<PathBuf> { None }
|
||||||
fn GetPerfInterface(&mut self, perf_callback: &mut retro_perf_callback) -> bool;
|
fn get_save_directory(&mut self) -> Option<PathBuf> { None }
|
||||||
fn GetLocationInterface(&mut self, location_callback: &mut retro_location_callback) -> bool;
|
fn set_system_av_info(&mut self, system_av_info: retro_system_av_info) -> bool { false }
|
||||||
fn GetCoreAssetsDirectory(&mut self, path: &mut PathBuf) -> bool;
|
fn set_proc_address_callback(&mut self, cb: retro_get_proc_address_interface) -> bool { false }
|
||||||
fn GetSaveDirectory(&mut self, path: &mut PathBuf) -> bool;
|
fn set_subsystem_info(&mut self, subsystem_info: retro_subsystem_info) -> bool { false }
|
||||||
fn SetSystemAvInfo(&mut self, system_av_info: retro_system_av_info) -> bool;
|
fn set_controller_info(&mut self, controller_info: retro_controller_info) -> bool { false }
|
||||||
fn SetProcAddressCallback(&mut self, get_proc_address_interface: retro_get_proc_address_interface) -> bool;
|
fn set_memory_maps(&mut self, memory_map: retro_memory_map) -> bool { false }
|
||||||
fn SetSubsystemInfo(&mut self, subsystem_info: retro_subsystem_info) -> bool;
|
fn set_geometry(&mut self, game_geometry: retro_game_geometry) -> bool { false }
|
||||||
fn SetControllerInfo(&mut self, controller_info: retro_controller_info) -> bool;
|
fn get_username(&mut self) -> Option<String> { None }
|
||||||
fn SetMemoryMaps(&mut self, memory_map: retro_memory_map) -> bool;
|
fn get_language(&mut self) -> Option<EnvLanguage> { None }
|
||||||
fn SetGeometry(&mut self, game_geometry: retro_game_geometry) -> bool;
|
fn set_serialization_quirks(&mut self, quirks: &mut u64) -> bool { false }
|
||||||
fn GetUsername(&mut self, username: &mut String) -> bool;
|
|
||||||
fn GetLanguage(&mut self, language: &mut EnvLanguage) -> bool;
|
|
||||||
fn SetSerializationQuirks(&mut self, quirks: &mut u64) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait HandlesVideoRefresh: Send + Sync + 'static {
|
pub trait HandlesVideoRefresh: Send + Sync + 'static {
|
||||||
fn video_refresh(&mut self, data: &[u8], width: c_uint, height: c_uint, pitch: c_uint);
|
fn video_refresh(&mut self, data: &[u8], width: c_uint, height: c_uint, pitch: c_uint);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,13 @@ use core::convert::TryInto;
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use core::slice::from_raw_parts;
|
use core::slice::from_raw_parts;
|
||||||
|
|
||||||
use std::os::raw::c_uint;
|
use std::ffi::CString;
|
||||||
|
use std::os::raw::{c_uint, c_char};
|
||||||
|
|
||||||
use crate::libretro_convert::*;
|
use crate::libretro_convert::*;
|
||||||
use crate::libretro_loading::*;
|
use crate::libretro_loading::*;
|
||||||
|
use std::path::Path;
|
||||||
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
|
|
||||||
static mut CB_SINGLETON: StaticCallbacks = StaticCallbacks {
|
static mut CB_SINGLETON: StaticCallbacks = StaticCallbacks {
|
||||||
environment: None,
|
environment: None,
|
||||||
|
@ -29,13 +32,80 @@ struct StaticCallbacks {
|
||||||
unsafe impl Sync for StaticCallbacks {}
|
unsafe impl Sync for StaticCallbacks {}
|
||||||
|
|
||||||
impl StaticCallbacks {
|
impl StaticCallbacks {
|
||||||
|
// helpers for environ cb
|
||||||
|
fn clone_into_void<T: Clone>(data: *mut c_void, source: &T) -> Option<bool> {
|
||||||
|
unsafe { (data as *mut T).as_mut() }?.clone_from(source);
|
||||||
|
Some(true)
|
||||||
|
}
|
||||||
|
fn string_into_void(data: *mut c_void, source: impl AsRef<str>) -> Option<bool> {
|
||||||
|
*unsafe { (data as *mut *const c_char).as_mut()? } = CString::new(source.as_ref()).ok()?.into_raw();
|
||||||
|
Some(true)
|
||||||
|
}
|
||||||
|
fn path_into_void(data: *mut c_void, source: impl AsRef<Path>) -> Option<bool> {
|
||||||
|
Self::string_into_void(data, source.as_ref().to_string_lossy())
|
||||||
|
}
|
||||||
|
fn from_void<T>(data: *mut c_void) -> Option<&'static mut T> {
|
||||||
|
unsafe { (data as *mut T).as_mut() }
|
||||||
|
}
|
||||||
|
fn enum_from_void<T>(data: *mut c_void) -> Option<T>
|
||||||
|
where T: TryFromPrimitive, <T as TryFromPrimitive>::Primitive: 'static
|
||||||
|
{
|
||||||
|
let number = Self::from_void(data).cloned()?;
|
||||||
|
T::try_from_primitive(number).ok()
|
||||||
|
}
|
||||||
|
fn environment_cb_inner(cmd: u32, data: *mut c_void) -> Option<bool> {
|
||||||
|
let mut handler = unsafe { CB_SINGLETON.environment.as_mut() }?;
|
||||||
|
match cmd.try_into().ok()? {
|
||||||
|
EnvironmentCmdData::SetRotation => handler.set_rotation(Self::enum_from_void(data)?),
|
||||||
|
EnvironmentCmdData::GetOverscan => Self::clone_into_void(data, &handler.get_overscan()?)?,
|
||||||
|
EnvironmentCmdData::GetCanDupe => Self::clone_into_void(data, &handler.get_can_dupe()?)?,
|
||||||
|
EnvironmentCmdData::SetMessage => handler.set_message(*Self::from_void(data)?),
|
||||||
|
EnvironmentCmdData::Shutdown => handler.shutdown(),
|
||||||
|
EnvironmentCmdData::SetPerformanceLevel => handler.set_performance_level(*Self::from_void(data)?),
|
||||||
|
EnvironmentCmdData::GetSystemDirectory => Self::path_into_void(data, handler.get_system_directory()?)?,
|
||||||
|
EnvironmentCmdData::SetPixelFormat => handler.set_pixel_format(Self::enum_from_void(data)?),
|
||||||
|
// TODO EnvironmentCmdData::SetInputDescriptors => {},
|
||||||
|
// TODO EnvironmentCmdData::SetKeyboardCallback => {},
|
||||||
|
// TODO EnvironmentCmdData::SetDiskControlInterface => {},
|
||||||
|
// TODO EnvironmentCmdData::SetHwRender => {},
|
||||||
|
// TODO EnvironmentCmdData::GetVariable => {}, -- also change to mut parameter?
|
||||||
|
// TODO EnvironmentCmdData::SetVariables => {},
|
||||||
|
EnvironmentCmdData::GetVariableUpdate => Self::clone_into_void(data, &handler.get_variable_update()?)?,
|
||||||
|
EnvironmentCmdData::SetSupportNoGame => handler.set_support_no_game(*Self::from_void(data)?),
|
||||||
|
EnvironmentCmdData::GetLibretroPath => Self::path_into_void(data, handler.get_libretro_path()?)?,
|
||||||
|
// TODO EnvironmentCmdData::SetFrameTimeCallback => {},
|
||||||
|
// TODO EnvironmentCmdData::SetAudioCallback => {},
|
||||||
|
// TODO EnvironmentCmdData::GetRumbleInterface => {},
|
||||||
|
EnvironmentCmdData::GetInputDeviceCapabilities => Self::clone_into_void(data, &handler.get_input_device_capabilities()?)?,
|
||||||
|
// TODO EnvironmentCmdData::GetSensorInterface => {},
|
||||||
|
// TODO EnvironmentCmdData::GetCameraInterface => {},
|
||||||
|
// TODO EnvironmentCmdData::GetLogInterface => {},
|
||||||
|
// TODO EnvironmentCmdData::GetPerfInterface => {},
|
||||||
|
// TODO EnvironmentCmdData::GetLocationInterface => {},
|
||||||
|
EnvironmentCmdData::GetCoreAssetsDirectory => Self::path_into_void(data, handler.get_core_assets_directory()?)?,
|
||||||
|
EnvironmentCmdData::GetSaveDirectory => Self::path_into_void(data, handler.get_save_directory()?)?,
|
||||||
|
EnvironmentCmdData::SetSystemAvInfo => handler.set_system_av_info(*Self::from_void(data)?),
|
||||||
|
// TODO EnvironmentCmdData::SetProcAddressCallback => {},
|
||||||
|
// TODO EnvironmentCmdData::SetSubsystemInfo => {},
|
||||||
|
// TODO EnvironmentCmdData::SetControllerInfo => {},
|
||||||
|
// TODO EnvironmentCmdData::SetMemoryMaps => {},
|
||||||
|
EnvironmentCmdData::SetGeometry => handler.set_geometry(*Self::from_void(data)?),
|
||||||
|
EnvironmentCmdData::GetUsername => Self::string_into_void(data, handler.get_username()?)?,
|
||||||
|
EnvironmentCmdData::GetLanguage => Self::clone_into_void(data, &c_uint::from(handler.get_language()?))?,
|
||||||
|
EnvironmentCmdData::SetSerializationQuirks => handler.set_serialization_quirks(Self::from_void(data)?),
|
||||||
|
_ => false,
|
||||||
|
}.into()
|
||||||
|
}
|
||||||
extern "C" fn environment_cb(cmd: u32, data: *mut c_void) -> bool {
|
extern "C" fn environment_cb(cmd: u32, data: *mut c_void) -> bool {
|
||||||
match unsafe { CB_SINGLETON.environment.as_mut() } {
|
Self::environment_cb_inner(cmd, data).unwrap_or(false)
|
||||||
Some(cb) => cb.environment(cmd, data),
|
|
||||||
None => false,
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
extern "C" fn video_refresh_cb(data: *const c_void, width: c_uint, height: c_uint, pitch: usize) {
|
extern "C" fn video_refresh_cb(
|
||||||
|
data: *const c_void,
|
||||||
|
width: c_uint,
|
||||||
|
height: c_uint,
|
||||||
|
pitch: usize,
|
||||||
|
) {
|
||||||
if !data.is_null() {
|
if !data.is_null() {
|
||||||
if let Some(cb) = unsafe { CB_SINGLETON.video_refresh.as_mut() } {
|
if let Some(cb) = unsafe { CB_SINGLETON.video_refresh.as_mut() } {
|
||||||
let data = data as *const u8;
|
let data = data as *const u8;
|
||||||
|
@ -56,7 +126,7 @@ impl StaticCallbacks {
|
||||||
Some(cb) => match data.is_null() {
|
Some(cb) => match data.is_null() {
|
||||||
true => 0,
|
true => 0,
|
||||||
false => cb.audio_sample_batch(from_raw_parts(data, frames)),
|
false => cb.audio_sample_batch(from_raw_parts(data, frames)),
|
||||||
}
|
},
|
||||||
None => 0,
|
None => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,22 +144,34 @@ impl StaticCallbacks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_environment(cb: &'static mut dyn HandlesEnvironment) {
|
pub(crate) fn set_environment(cb: &'static mut dyn HandlesEnvironment) {
|
||||||
unsafe { CB_SINGLETON.environment.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.environment.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_video_refresh(cb: &'static mut dyn HandlesVideoRefresh) {
|
pub(crate) fn set_video_refresh(cb: &'static mut dyn HandlesVideoRefresh) {
|
||||||
unsafe { CB_SINGLETON.video_refresh.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.video_refresh.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_audio_sample(cb: &'static mut dyn HandlesAudioSample) {
|
pub(crate) fn set_audio_sample(cb: &'static mut dyn HandlesAudioSample) {
|
||||||
unsafe { CB_SINGLETON.audio_sample.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.audio_sample.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_audio_sample_batch(cb: &'static mut dyn HandlesAudioSampleBatch) {
|
pub(crate) fn set_audio_sample_batch(cb: &'static mut dyn HandlesAudioSampleBatch) {
|
||||||
unsafe { CB_SINGLETON.audio_sample_batch.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.audio_sample_batch.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_input_poll(cb: &'static mut dyn HandlesInputPoll) {
|
pub(crate) fn set_input_poll(cb: &'static mut dyn HandlesInputPoll) {
|
||||||
unsafe { CB_SINGLETON.input_poll.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.input_poll.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn set_input_state(cb: &'static mut dyn HandlesInputState) {
|
pub(crate) fn set_input_state(cb: &'static mut dyn HandlesInputState) {
|
||||||
unsafe { CB_SINGLETON.input_state.replace(cb); }
|
unsafe {
|
||||||
|
CB_SINGLETON.input_state.replace(cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn reset() {
|
pub(crate) fn reset() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -115,9 +197,7 @@ impl<'a> From<LibretroApi<'a>> for LibretroWrapper<'a> {
|
||||||
api.set_audio_sample_batch(Some(StaticCallbacks::audio_sample_batch_cb));
|
api.set_audio_sample_batch(Some(StaticCallbacks::audio_sample_batch_cb));
|
||||||
api.set_input_poll(Some(StaticCallbacks::input_poll_cb));
|
api.set_input_poll(Some(StaticCallbacks::input_poll_cb));
|
||||||
api.set_input_state(Some(StaticCallbacks::input_state_cb));
|
api.set_input_state(Some(StaticCallbacks::input_state_cb));
|
||||||
LibretroWrapper {
|
LibretroWrapper { api }
|
||||||
api,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +228,10 @@ impl<'a> LibretroWrapper<'a> {
|
||||||
let ptr: *mut dyn HandlesAudioSample = handler;
|
let ptr: *mut dyn HandlesAudioSample = handler;
|
||||||
StaticCallbacks::set_audio_sample(unsafe { ptr.as_mut() }.unwrap());
|
StaticCallbacks::set_audio_sample(unsafe { ptr.as_mut() }.unwrap());
|
||||||
}
|
}
|
||||||
pub fn register_audio_sample_batch_handler(&self, handler: &'a mut dyn HandlesAudioSampleBatch) {
|
pub fn register_audio_sample_batch_handler(
|
||||||
|
&self,
|
||||||
|
handler: &'a mut dyn HandlesAudioSampleBatch,
|
||||||
|
) {
|
||||||
let ptr: *mut dyn HandlesAudioSampleBatch = handler;
|
let ptr: *mut dyn HandlesAudioSampleBatch = handler;
|
||||||
StaticCallbacks::set_audio_sample_batch(unsafe { ptr.as_mut() }.unwrap());
|
StaticCallbacks::set_audio_sample_batch(unsafe { ptr.as_mut() }.unwrap());
|
||||||
}
|
}
|
||||||
|
@ -160,4 +243,20 @@ impl<'a> LibretroWrapper<'a> {
|
||||||
let ptr: *mut dyn HandlesInputState = handler;
|
let ptr: *mut dyn HandlesInputState = handler;
|
||||||
StaticCallbacks::set_input_state(unsafe { ptr.as_mut() }.unwrap());
|
StaticCallbacks::set_input_state(unsafe { ptr.as_mut() }.unwrap());
|
||||||
}
|
}
|
||||||
|
pub fn register_for_all<T>(&self, handler: &'a mut T)
|
||||||
|
where
|
||||||
|
T: HandlesEnvironment
|
||||||
|
+ HandlesVideoRefresh
|
||||||
|
+ HandlesAudioSample
|
||||||
|
+ HandlesAudioSampleBatch
|
||||||
|
+ HandlesInputPoll
|
||||||
|
+ HandlesInputState,
|
||||||
|
{
|
||||||
|
self.register_environment_handler(handler);
|
||||||
|
self.register_video_refresh_handler(handler);
|
||||||
|
self.register_audio_sample_handler(handler);
|
||||||
|
self.register_audio_sample_batch_handler(handler);
|
||||||
|
self.register_input_poll_handler(handler);
|
||||||
|
self.register_input_state_handler(handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
155
src/main.rs
155
src/main.rs
|
@ -7,7 +7,7 @@ mod libretro_loading;
|
||||||
mod libretro_convert;
|
mod libretro_convert;
|
||||||
mod libretro_wrapper;
|
mod libretro_wrapper;
|
||||||
|
|
||||||
use std::ffi::{CStr, c_void};
|
use std::ffi::CStr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
@ -16,159 +16,6 @@ use crate::libretro_convert::{HandlesEnvironment, HandlesVideoRefresh};
|
||||||
|
|
||||||
struct Foo;
|
struct Foo;
|
||||||
impl HandlesEnvironment for Foo {
|
impl HandlesEnvironment for Foo {
|
||||||
fn environment(&mut self, cmd: u32, data: *mut c_void) -> bool {
|
|
||||||
println!("environment cmd: {}", cmd);
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetRotation(&mut self, rotation: EnvRotation) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetOverscan(&mut self, overscan: &mut bool) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetCanDupe(&mut self, frame_duping: &mut bool) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetMessage(&mut self, message: retro_message) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn Shutdown(&mut self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetPerformanceLevel(&mut self, level: c_uint) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetSystemDirectory(&mut self, path: &mut PathBuf) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetPixelFormat(&mut self, format: EnvPixelFormat) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetInputDescriptors(&mut self, input_descriptors: &[retro_input_descriptor]) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetKeyboardCallback(&mut self, keyboard_callback: retro_keyboard_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetDiskControlInterface(&mut self, disk_control_callback: retro_disk_control_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetHwRender(&mut self, hw_render_callback: retro_hw_render_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetVariable(&mut self, variable: &mut EnvVariable) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetVariables(&mut self, variables: &[EnvVariable]) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetVariableUpdate(&mut self, variables_updated: &mut bool) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetSupportNoGame(&mut self, supports_no_game: bool) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetLibretroPath(&mut self, path: &mut PathBuf) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetFrameTimeCallback(&mut self, frame_time_callback: retro_frame_time_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetAudioCallback(&mut self, audio_callback: retro_audio_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetRumbleInterface(&mut self, rumble_interface: &mut retro_rumble_interface) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetInputDeviceCapabilities(&mut self, input_device_capabilities: &mut u64) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetSensorInterface(&mut self, sensor_interface: &mut retro_sensor_interface) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetCameraInterface(&mut self, camera_callback: &mut retro_camera_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetLogInterface(&mut self, log_callback: &mut retro_log_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetPerfInterface(&mut self, perf_callback: &mut retro_perf_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetLocationInterface(&mut self, location_callback: &mut retro_location_callback) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetCoreAssetsDirectory(&mut self, path: &mut PathBuf) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetSaveDirectory(&mut self, path: &mut PathBuf) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetSystemAvInfo(&mut self, system_av_info: retro_system_av_info) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetProcAddressCallback(&mut self, get_proc_address_interface: retro_get_proc_address_interface) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetSubsystemInfo(&mut self, subsystem_info: retro_subsystem_info) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetControllerInfo(&mut self, controller_info: retro_controller_info) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetMemoryMaps(&mut self, memory_map: retro_memory_map) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetGeometry(&mut self, game_geometry: retro_game_geometry) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetUsername(&mut self, username: &mut String) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetLanguage(&mut self, language: &mut EnvLanguage) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetSerializationQuirks(&mut self, quirks: &mut u64) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HandlesVideoRefresh for Foo {
|
impl HandlesVideoRefresh for Foo {
|
||||||
|
|
Loading…
Reference in New Issue