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::os::raw::{c_uint, c_void};
|
||||
use std::os::raw::c_uint;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use num_enum::TryFromPrimitive;
|
||||
use num_enum::{TryFromPrimitive, IntoPrimitive};
|
||||
|
||||
use crate::libretro_ffi::*;
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum Region {
|
||||
NTSC = RETRO_REGION_NTSC,
|
||||
PAL = RETRO_REGION_PAL,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum DeviceType {
|
||||
None = RETRO_DEVICE_NONE,
|
||||
|
@ -25,7 +25,7 @@ pub enum DeviceType {
|
|||
Pointer = RETRO_DEVICE_POINTER,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum DeviceIndex {
|
||||
Left = RETRO_DEVICE_INDEX_ANALOG_LEFT,
|
||||
|
@ -33,7 +33,7 @@ pub enum DeviceIndex {
|
|||
Button = RETRO_DEVICE_INDEX_ANALOG_BUTTON,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum JoypadButton {
|
||||
B = RETRO_DEVICE_ID_JOYPAD_B,
|
||||
|
@ -54,14 +54,14 @@ pub enum JoypadButton {
|
|||
R3 = RETRO_DEVICE_ID_JOYPAD_R3,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum AnalogAxis {
|
||||
X = RETRO_DEVICE_ID_ANALOG_X,
|
||||
Y = RETRO_DEVICE_ID_ANALOG_Y,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum MouseButton {
|
||||
X = RETRO_DEVICE_ID_MOUSE_X,
|
||||
|
@ -77,7 +77,7 @@ pub enum MouseButton {
|
|||
Button5 = RETRO_DEVICE_ID_MOUSE_BUTTON_5,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum LightGunButton {
|
||||
ScreenX = RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X,
|
||||
|
@ -99,7 +99,7 @@ pub enum LightGunButton {
|
|||
Pause = RETRO_DEVICE_ID_LIGHTGUN_PAUSE,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum PointerStat {
|
||||
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)]
|
||||
pub enum EnvRotation {
|
||||
None = 0,
|
||||
|
@ -146,7 +146,7 @@ pub enum EnvRotation {
|
|||
CounterClockwise270 = 3,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum EnvPixelFormat {
|
||||
XRGB555 = retro_pixel_format_RETRO_PIXEL_FORMAT_0RGB1555,
|
||||
|
@ -162,7 +162,7 @@ pub struct EnvVariable {
|
|||
value: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(TryFromPrimitive)]
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum EnvLanguage {
|
||||
English = retro_language_RETRO_LANGUAGE_ENGLISH,
|
||||
|
@ -186,90 +186,89 @@ pub enum EnvLanguage {
|
|||
Last = retro_language_RETRO_LANGUAGE_LAST,
|
||||
}
|
||||
|
||||
// TODO: lifetime
|
||||
// TODO: experimental calls
|
||||
#[derive(TryFromPrimitive, IntoPrimitive)]
|
||||
#[repr(u32)]
|
||||
pub enum EnvironmentCmdData {
|
||||
SetRotation(EnvRotation),
|
||||
GetOverscan(&'static mut bool),
|
||||
GetCanDupe(&'static mut bool),
|
||||
SetMessage(retro_message), // TODO
|
||||
Shutdown,
|
||||
SetPerformanceLevel(c_uint),
|
||||
GetSystemDirectory(&'static mut PathBuf),
|
||||
SetPixelFormat(EnvPixelFormat),
|
||||
SetInputDescriptors(&'static [retro_input_descriptor]), // TODO
|
||||
SetKeyboardCallback(retro_keyboard_callback), // TODO
|
||||
SetDiskControlInterface(retro_disk_control_callback), // TODO
|
||||
SetHwRender(retro_hw_render_callback), // TODO
|
||||
GetVariable(&'static mut EnvVariable),
|
||||
SetVariables(&'static [EnvVariable]),
|
||||
GetVariableUpdate(&'static mut bool),
|
||||
SetSupportNoGame(bool),
|
||||
GetLibretroPath(&'static mut PathBuf),
|
||||
SetFrameTimeCallback(retro_frame_time_callback), // TODO
|
||||
SetAudioCallback(retro_audio_callback), // TODO
|
||||
GetRumbleInterface(&'static mut retro_rumble_interface), // TODO
|
||||
GetInputDeviceCapabilities(&'static mut u64), // TODO
|
||||
GetSensorInterface(&'static mut retro_sensor_interface), // TODO
|
||||
GetCameraInterface(&'static mut retro_camera_callback), // TODO
|
||||
GetLogInterface(&'static mut retro_log_callback), // TODO
|
||||
GetPerfInterface(&'static mut retro_perf_callback), // TODO
|
||||
GetLocationInterface(&'static mut retro_location_callback), // TODO
|
||||
GetCoreAssetsDirectory(&'static mut PathBuf),
|
||||
GetSaveDirectory(&'static mut PathBuf),
|
||||
SetSystemAvInfo(retro_system_av_info),
|
||||
SetProcAddressCallback(retro_get_proc_address_interface), // TODO
|
||||
SetSubsystemInfo(retro_subsystem_info), // TODO
|
||||
SetControllerInfo(retro_controller_info), // TODO
|
||||
SetMemoryMaps(retro_memory_map), // TODO
|
||||
SetGeometry(retro_game_geometry), // TODO
|
||||
GetUsername(&'static mut String),
|
||||
GetLanguage(&'static mut EnvLanguage),
|
||||
SetSerializationQuirks(&'static mut u64), // TODO
|
||||
SetRotation = RETRO_ENVIRONMENT_SET_ROTATION,
|
||||
GetOverscan = RETRO_ENVIRONMENT_GET_OVERSCAN,
|
||||
GetCanDupe = RETRO_ENVIRONMENT_GET_CAN_DUPE,
|
||||
SetMessage = RETRO_ENVIRONMENT_SET_MESSAGE,
|
||||
Shutdown = RETRO_ENVIRONMENT_SHUTDOWN,
|
||||
SetPerformanceLevel = RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL,
|
||||
GetSystemDirectory = RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY,
|
||||
SetPixelFormat = RETRO_ENVIRONMENT_SET_PIXEL_FORMAT,
|
||||
SetInputDescriptors = RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS,
|
||||
SetKeyboardCallback = RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK,
|
||||
SetDiskControlInterface = RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE,
|
||||
SetHwRender = RETRO_ENVIRONMENT_SET_HW_RENDER,
|
||||
GetVariable = RETRO_ENVIRONMENT_GET_VARIABLE,
|
||||
SetVariables = RETRO_ENVIRONMENT_SET_VARIABLES,
|
||||
GetVariableUpdate = RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE,
|
||||
SetSupportNoGame = RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME,
|
||||
GetLibretroPath = RETRO_ENVIRONMENT_GET_LIBRETRO_PATH,
|
||||
SetFrameTimeCallback = RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK,
|
||||
SetAudioCallback = RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK,
|
||||
GetRumbleInterface = RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE,
|
||||
GetInputDeviceCapabilities = RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES,
|
||||
GetSensorInterface = RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE,
|
||||
GetCameraInterface = RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE,
|
||||
GetLogInterface = RETRO_ENVIRONMENT_GET_LOG_INTERFACE,
|
||||
GetPerfInterface = RETRO_ENVIRONMENT_GET_PERF_INTERFACE,
|
||||
GetLocationInterface = RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE,
|
||||
GetCoreAssetsDirectory = RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY,
|
||||
GetSaveDirectory = RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY,
|
||||
SetSystemAvInfo = RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO,
|
||||
SetProcAddressCallback = RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK,
|
||||
SetSubsystemInfo = RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO,
|
||||
SetControllerInfo = RETRO_ENVIRONMENT_SET_CONTROLLER_INFO,
|
||||
SetMemoryMaps = RETRO_ENVIRONMENT_SET_MEMORY_MAPS,
|
||||
SetGeometry = RETRO_ENVIRONMENT_SET_GEOMETRY,
|
||||
GetUsername = RETRO_ENVIRONMENT_GET_USERNAME,
|
||||
GetLanguage = RETRO_ENVIRONMENT_GET_LANGUAGE,
|
||||
SetSerializationQuirks = RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS,
|
||||
}
|
||||
|
||||
pub trait HandlesEnvironment: Send + Sync + 'static {
|
||||
// TODO: wrap cmd+data in enum
|
||||
fn environment(&mut self, cmd: u32, data: *mut c_void) -> bool;
|
||||
|
||||
fn SetRotation(&mut self, rotation: EnvRotation) -> bool;
|
||||
fn GetOverscan(&mut self, overscan: &mut bool) -> bool;
|
||||
fn GetCanDupe(&mut self, frame_duping: &mut bool) -> bool;
|
||||
fn SetMessage(&mut self, message: retro_message) -> bool;
|
||||
fn Shutdown(&mut self) -> bool;
|
||||
fn SetPerformanceLevel(&mut self, level: c_uint) -> bool;
|
||||
fn GetSystemDirectory(&mut self, path: &mut PathBuf) -> bool;
|
||||
fn SetPixelFormat(&mut self, format: EnvPixelFormat) -> bool;
|
||||
fn SetInputDescriptors(&mut self, input_descriptors: &[retro_input_descriptor]) -> bool;
|
||||
fn SetKeyboardCallback(&mut self, keyboard_callback: retro_keyboard_callback) -> bool;
|
||||
fn SetDiskControlInterface(&mut self, disk_control_callback: retro_disk_control_callback) -> bool;
|
||||
fn SetHwRender(&mut self, hw_render_callback: retro_hw_render_callback) -> bool;
|
||||
fn GetVariable(&mut self, variable: &mut EnvVariable) -> bool;
|
||||
fn SetVariables(&mut self, variables: &[EnvVariable]) -> bool;
|
||||
fn GetVariableUpdate(&mut self, variables_updated: &mut bool) -> bool;
|
||||
fn SetSupportNoGame(&mut self, supports_no_game: bool) -> bool;
|
||||
fn GetLibretroPath(&mut self, path: &mut PathBuf) -> bool;
|
||||
fn SetFrameTimeCallback(&mut self, frame_time_callback: retro_frame_time_callback) -> bool;
|
||||
fn SetAudioCallback(&mut self, audio_callback: retro_audio_callback) -> bool;
|
||||
fn GetRumbleInterface(&mut self, rumble_interface: &mut retro_rumble_interface) -> bool;
|
||||
fn GetInputDeviceCapabilities(&mut self, input_device_capabilities: &mut u64) -> bool;
|
||||
fn GetSensorInterface(&mut self, sensor_interface: &mut retro_sensor_interface) -> bool;
|
||||
fn GetCameraInterface(&mut self, camera_callback: &mut retro_camera_callback) -> bool;
|
||||
fn GetLogInterface(&mut self, log_callback: &mut retro_log_callback) -> bool;
|
||||
fn GetPerfInterface(&mut self, perf_callback: &mut retro_perf_callback) -> bool;
|
||||
fn GetLocationInterface(&mut self, location_callback: &mut retro_location_callback) -> bool;
|
||||
fn GetCoreAssetsDirectory(&mut self, path: &mut PathBuf) -> bool;
|
||||
fn GetSaveDirectory(&mut self, path: &mut PathBuf) -> bool;
|
||||
fn SetSystemAvInfo(&mut self, system_av_info: retro_system_av_info) -> bool;
|
||||
fn SetProcAddressCallback(&mut self, get_proc_address_interface: retro_get_proc_address_interface) -> bool;
|
||||
fn SetSubsystemInfo(&mut self, subsystem_info: retro_subsystem_info) -> bool;
|
||||
fn SetControllerInfo(&mut self, controller_info: retro_controller_info) -> bool;
|
||||
fn SetMemoryMaps(&mut self, memory_map: retro_memory_map) -> bool;
|
||||
fn SetGeometry(&mut self, game_geometry: retro_game_geometry) -> bool;
|
||||
fn GetUsername(&mut self, username: &mut String) -> bool;
|
||||
fn GetLanguage(&mut self, language: &mut EnvLanguage) -> bool;
|
||||
fn SetSerializationQuirks(&mut self, quirks: &mut u64) -> bool;
|
||||
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: retro_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: EnvPixelFormat) -> bool { false }
|
||||
fn set_input_descriptors(&mut self, input_descriptors: &[retro_input_descriptor]) -> bool { false }
|
||||
fn set_keyboard_callback(&mut self, cb: retro_keyboard_callback) -> bool { false }
|
||||
fn set_disk_control_interface(&mut self, cb: retro_disk_control_callback) -> bool { false }
|
||||
fn set_hw_render(&mut self, hw_render_callback: retro_hw_render_callback) -> 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: retro_frame_time_callback) -> bool { false }
|
||||
fn set_audio_callback(&mut self, audio_callback: retro_audio_callback) -> bool { false }
|
||||
fn get_rumble_interface(&mut self) -> Option<retro_rumble_interface> { None }
|
||||
fn get_input_device_capabilities(&mut self) -> Option<u64> { None }
|
||||
fn get_sensor_interface(&mut self) -> Option<retro_sensor_interface> { None }
|
||||
fn get_camera_interface(&mut self) -> Option<retro_camera_callback> { None }
|
||||
fn get_log_interface(&mut self) -> Option<retro_log_callback> { None }
|
||||
fn get_perf_interface(&mut self) -> Option<retro_perf_callback> { None }
|
||||
fn get_location_interface(&mut self) -> Option<retro_location_callback> { 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: retro_system_av_info) -> bool { false }
|
||||
fn set_proc_address_callback(&mut self, cb: retro_get_proc_address_interface) -> bool { false }
|
||||
fn set_subsystem_info(&mut self, subsystem_info: retro_subsystem_info) -> bool { false }
|
||||
fn set_controller_info(&mut self, controller_info: retro_controller_info) -> bool { false }
|
||||
fn set_memory_maps(&mut self, memory_map: retro_memory_map) -> bool { false }
|
||||
fn set_geometry(&mut self, game_geometry: retro_game_geometry) -> bool { false }
|
||||
fn get_username(&mut self) -> Option<String> { None }
|
||||
fn get_language(&mut self) -> Option<EnvLanguage> { None }
|
||||
fn set_serialization_quirks(&mut self, quirks: &mut u64) -> bool { false }
|
||||
}
|
||||
|
||||
pub trait HandlesVideoRefresh: Send + Sync + 'static {
|
||||
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::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_loading::*;
|
||||
use std::path::Path;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
||||
static mut CB_SINGLETON: StaticCallbacks = StaticCallbacks {
|
||||
environment: None,
|
||||
|
@ -29,13 +32,80 @@ struct StaticCallbacks {
|
|||
unsafe impl Sync for StaticCallbacks {}
|
||||
|
||||
impl StaticCallbacks {
|
||||
extern "C" fn environment_cb(cmd: u32, data: *mut c_void) -> bool {
|
||||
match unsafe { CB_SINGLETON.environment.as_mut() } {
|
||||
Some(cb) => cb.environment(cmd, data),
|
||||
None => false,
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
extern "C" fn video_refresh_cb(data: *const c_void, width: c_uint, height: c_uint, pitch: usize) {
|
||||
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 {
|
||||
Self::environment_cb_inner(cmd, data).unwrap_or(false)
|
||||
}
|
||||
|
||||
extern "C" fn video_refresh_cb(
|
||||
data: *const c_void,
|
||||
width: c_uint,
|
||||
height: c_uint,
|
||||
pitch: usize,
|
||||
) {
|
||||
if !data.is_null() {
|
||||
if let Some(cb) = unsafe { CB_SINGLETON.video_refresh.as_mut() } {
|
||||
let data = data as *const u8;
|
||||
|
@ -56,7 +126,7 @@ impl StaticCallbacks {
|
|||
Some(cb) => match data.is_null() {
|
||||
true => 0,
|
||||
false => cb.audio_sample_batch(from_raw_parts(data, frames)),
|
||||
}
|
||||
},
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
@ -74,22 +144,34 @@ impl StaticCallbacks {
|
|||
}
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
unsafe { CB_SINGLETON.input_state.replace(cb); }
|
||||
unsafe {
|
||||
CB_SINGLETON.input_state.replace(cb);
|
||||
}
|
||||
}
|
||||
pub(crate) fn reset() {
|
||||
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_input_poll(Some(StaticCallbacks::input_poll_cb));
|
||||
api.set_input_state(Some(StaticCallbacks::input_state_cb));
|
||||
LibretroWrapper {
|
||||
api,
|
||||
}
|
||||
LibretroWrapper { api }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,7 +228,10 @@ impl<'a> LibretroWrapper<'a> {
|
|||
let ptr: *mut dyn HandlesAudioSample = handler;
|
||||
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;
|
||||
StaticCallbacks::set_audio_sample_batch(unsafe { ptr.as_mut() }.unwrap());
|
||||
}
|
||||
|
@ -160,4 +243,20 @@ impl<'a> LibretroWrapper<'a> {
|
|||
let ptr: *mut dyn HandlesInputState = handler;
|
||||
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_wrapper;
|
||||
|
||||
use std::ffi::{CStr, c_void};
|
||||
use std::ffi::CStr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
@ -16,159 +16,6 @@ use crate::libretro_convert::{HandlesEnvironment, HandlesVideoRefresh};
|
|||
|
||||
struct 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 {
|
||||
|
|
Loading…
Reference in New Issue