WIP camera

This commit is contained in:
lifning 2021-10-01 20:43:44 -07:00
parent 79f6d79eb8
commit 41ffd86d1b
4 changed files with 82 additions and 3 deletions

View File

@ -365,6 +365,11 @@ pub trait RetroCallbacks: Unpin + 'static {
fn perf_stop(&mut self, counter: &mut PerfCounter) {}
fn set_sensor_state(&mut self, port: c_uint, action: SensorAction, rate: c_uint) -> bool { false }
fn get_sensor_input(&mut self, port: c_uint, id: c_uint) -> f32 { 0.0 }
fn get_camera_interface(&mut self, width: c_uint, height: c_uint, cap_raw_fb: bool, cap_gl_tex: bool) -> Option<bool> { None }
/// Starts the camera driver. Can only be called in retro_run().
fn camera_start(&mut self) -> Option<bool> { None }
/// Stops the camera driver. Can only be called in retro_run().
fn camera_stop(&mut self) -> Option<()> { None }
/// Gets current framebuffer which is to be rendered to.
/// Could change every frame potentially.
fn hw_get_current_framebuffer(&mut self) -> Option<usize> { None }
@ -547,7 +552,27 @@ impl StaticCallbacks {
};
Self::clone_into_void(data, &si)?
}
// TODO (apathy) EnvCmd::GetCameraInterface => {},
EnvCmd::GetCameraInterface => {
let cc: &mut CameraCallback = Self::from_void(data)?;
let gl_tex = (cc.caps & 1 << (CameraBuffer::OpenGLTexture as u64)) != 0;
let raw_fb = (cc.caps & 1 << (CameraBuffer::RawFramebuffer as u64)) != 0;
let wrapper = handler.libretro_core();
if !(cc.frame_raw_framebuffer as *const ()).is_null() {
wrapper.camera_frame_raw_framebuffer_cb.replace(cc.frame_raw_framebuffer);
}
if !(cc.frame_opengl_texture as *const ()).is_null() {
wrapper.camera_frame_opengl_texture_cb.replace(cc.frame_opengl_texture);
}
if !(cc.initialized as *const ()).is_null() {
wrapper.camera_lifetime_initialized_cb.replace(cc.initialized);
}
if !(cc.deinitialized as *const ()).is_null() {
wrapper.camera_lifetime_deinitialized_cb.replace(cc.deinitialized);
}
cc.start = Self::camera_start;
cc.stop = Self::camera_stop;
handler.get_camera_interface(cc.width, cc.height, gl_tex, raw_fb)?
}
EnvCmd::GetLogInterface => unsafe {
c_ext_handle_get_log_interface(data as *mut LogCallback)
}
@ -750,6 +775,17 @@ impl StaticCallbacks {
}.unwrap_or_default()
}
extern "C" fn camera_start() -> bool {
unsafe {
CB_SINGLETON.handler.as_mut().and_then(|cb| cb.camera_start())
}.unwrap_or_default()
}
extern "C" fn camera_stop() -> () {
unsafe {
CB_SINGLETON.handler.as_mut().and_then(|cb| cb.camera_stop())
}.unwrap_or_default()
}
extern "C" fn hw_get_proc_address_fn(sym: *const c_char) -> ProcAddressFn {
unsafe {
std::mem::transmute(
@ -781,6 +817,10 @@ pub struct LibretroWrapper {
disk_get_num_images_cb: Option<GetNumImagesFn>,
disk_replace_image_index_cb: Option<ReplaceImageIndexFn>,
disk_add_image_index_cb: Option<AddImageIndexFn>,
camera_frame_raw_framebuffer_cb: Option<CameraFrameRawFramebufferFn>,
camera_frame_opengl_texture_cb: Option<CameraFrameOpenglTextureFn>,
camera_lifetime_initialized_cb: Option<CameraLifetimeStatusFn>,
camera_lifetime_deinitialized_cb: Option<CameraLifetimeStatusFn>,
hw_context_reset_cb: Option<HwContextResetFn>,
hw_context_destroy_cb: Option<HwContextResetFn>, // same signature, libretro-sys deduplicated...
get_proc_address_cb: Option<GetProcAddressFn>,
@ -801,6 +841,10 @@ impl From<LibretroApi> for LibretroWrapper {
disk_get_num_images_cb: None,
disk_replace_image_index_cb: None,
disk_add_image_index_cb: None,
camera_frame_raw_framebuffer_cb: None,
camera_frame_opengl_texture_cb: None,
camera_lifetime_initialized_cb: None,
camera_lifetime_deinitialized_cb: None,
hw_context_reset_cb: None,
hw_context_destroy_cb: None,
get_proc_address_cb: None,
@ -820,16 +864,19 @@ impl LibretroWrapper {
self.keyboard_event_cb
.map(|f| unsafe { f(down, keycode, character, key_modifiers) })
}
pub fn frame_time(&self, time: Duration) -> Option<()> {
self.frame_time_cb
.map(|f| unsafe { f(time.as_micros() as Usec) })
}
pub fn audio_ready(&self) -> Option<()> {
self.audio_ready_cb.map(|f| unsafe { f() })
}
pub fn audio_set_state(&self, enabled: bool) -> Option<()> {
self.audio_set_state_cb.map(|f| unsafe { f(enabled) })
}
pub fn disk_get_eject_state(&self) -> Option<bool> {
self.disk_get_eject_state_cb.map(|f| unsafe { f() })
}
@ -857,6 +904,20 @@ impl LibretroWrapper {
pub fn disk_add_image_index(&self) -> Option<bool> {
self.disk_add_image_index_cb.map(|f| unsafe { f() })
}
pub fn camera_frame_raw_framebuffer(&self, buffer: *const u32, width: c_uint, height: c_uint, pitch: usize) -> Option<()> {
self.camera_frame_raw_framebuffer_cb.map(|f| unsafe { f(buffer, width, height, pitch) })
}
pub fn camera_frame_opengl_texture(&self, texture_id: c_uint, texture_target: c_uint, affine: *const f32) -> Option<()> {
self.camera_frame_opengl_texture_cb.map(|f| unsafe { f(texture_id, texture_target, affine) })
}
pub fn camera_lifetime_initialized(&self) -> Option<()> {
self.camera_lifetime_initialized_cb.map(|f| unsafe { f() })
}
pub fn camera_lifetime_deinitialized(&self) -> Option<()> {
self.camera_lifetime_deinitialized_cb.map(|f| unsafe { f() })
}
pub fn hw_context_reset(&self) -> Option<()> {
self.hw_context_reset_cb.map(|f| unsafe { f() })
}

View File

@ -14,6 +14,7 @@ use ferretro_components::provided::{
stdlib::{PathBufComponent, StderrLogComponent, SleepFramerateLimitComponent},
};
use ferretro_components::base::ControlFlow;
use ferretro_components::provided::stdlib::{StderrCallTraceComponent, StderrSysInfoLogComponent};
#[derive(StructOpt)]
struct Opt {
@ -42,8 +43,10 @@ pub fn main() {
let mut sdl_context = sdl2::init().unwrap();
emu.register_component(StderrLogComponent { prefix: "{log} ".to_string() });
emu.register_component(StderrCallTraceComponent { prefix: "{trace} ".to_string() });
emu.register_component(StderrSysInfoLogComponent { prefix: "{sysinfo} ".to_string() });
let sdl2_ogl = SimpleSdl2OpenglComponent::new(&mut sdl_context, emu.libretro_core()).unwrap();
let sdl2_ogl = SimpleSdl2CanvasComponent::new(&mut sdl_context, emu.libretro_core()).unwrap();
emu.register_component(sdl2_ogl);
let sdl2_audio = SimpleSdl2AudioComponent::new(&mut sdl_context, emu.libretro_core());

View File

@ -63,8 +63,11 @@ impl RetroCallbacks for SimpleSdl2CanvasComponent {
}
fn get_variable(&mut self, key: &str) -> Option<String> {
eprintln!("get_variable({})", key);
match key {
"parallel-n64-gfxplugin" => Some("angrylion".to_string()),
"mupen64plus-rdp-plugin" => Some("angrylion".to_string()),
"mupen64plus-rsp-plugin" => Some("cxd4".to_string()),
_ => None,
}
}

View File

@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
use crate::base::ControlFlow;
use crate::prelude::*;
use ferretro_base::retro::ffi::{Message, Language};
use ferretro_base::retro::ffi::{Message, Language, LogLevel, RumbleEffect, Time, PerfTick, PerfCounter, SensorAction};
#[derive(Default)]
pub struct PathBufComponent {
@ -197,6 +197,18 @@ impl RetroCallbacks for StderrCallTraceComponent {
eprintln!("{}get_language()", self.prefix);
None
}
fn get_camera_interface(&mut self, width: c_uint, height: c_uint, cap_raw_fb: bool, cap_gl_tex: bool) -> Option<bool> {
eprintln!("{}get_camera_interface(width={}, height={}, fb={}, gl={})", self.prefix, width, height, cap_raw_fb, cap_gl_tex);
None
}
fn camera_start(&mut self) -> Option<bool> {
eprintln!("{}camera_start()", self.prefix);
None
}
fn camera_stop(&mut self) -> Option<()> {
eprintln!("{}camera_stop()", self.prefix);
None
}
fn hw_get_current_framebuffer(&mut self) -> Option<usize> {
eprintln!("{}hw_get_current_framebuffer()", self.prefix);
None