log support

This commit is contained in:
lif 2019-11-16 21:34:01 -08:00
parent 140f988e99
commit d9f1d789ca
6 changed files with 64 additions and 2 deletions

View File

@ -4,6 +4,9 @@ version = "0.1.0"
authors = ["lifning <lifning+git@pm.me>"]
edition = "2018"
[build-dependencies]
cc = "^1"
[dependencies]
libretro-sys = "^0.1"
failure = "^0.1"

6
build.rs Normal file
View File

@ -0,0 +1,6 @@
fn main() {
cc::Build::new()
.file("src/retro/c_ext/log_wrapper.c")
.compile("log_wrapper");
}

View File

@ -261,6 +261,10 @@ impl retro::wrapper::Handler for MyEmulator {
self.av_info.geometry = geom;
true
}
fn log_print(&mut self, level: retro::ffi::LogLevel, msg: &str) {
eprint!("[{:?}] {}", level, msg);
}
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdarg.h>
#include "libretro.h"
typedef void (*rust_retro_ffi_log_print_t)(enum retro_log_level level, const char* msg);
rust_retro_ffi_log_print_t g_rust_retro_ffi_log_print = NULL;
void retro_log_snprintf_wrapper(enum retro_log_level level, const char* fmt, ...)
{
if (g_rust_retro_ffi_log_print != NULL)
{
char msg[4096];
va_list args;
va_start(args, fmt);
vsnprintf(msg, sizeof(msg), fmt, args);
va_end(args);
g_rust_retro_ffi_log_print(level, msg);
}
}
bool c_ext_handle_get_log_interface(struct retro_log_callback* retro_cb)
{
retro_cb->log = retro_log_snprintf_wrapper;
return true;
}
void c_ext_set_log_print_cb(rust_retro_ffi_log_print_t cb)
{
g_rust_retro_ffi_log_print = cb;
}

View File

@ -2,7 +2,7 @@ use core::convert::TryInto;
use core::ffi::c_void;
use core::slice::from_raw_parts;
use std::ffi::CString;
use std::ffi::{CString, CStr};
use std::os::raw::{c_uint, c_char};
use std::path::{Path, PathBuf};
use std::pin::Pin;
@ -17,6 +17,19 @@ static mut CB_SINGLETON: StaticCallbacks = StaticCallbacks {
handler: None,
};
pub type WrappedLogPrintFn = extern "C" fn(level: LogLevel, fmt: *const c_char);
extern "C" {
fn c_ext_handle_get_log_interface(cb: *mut LogCallback) -> bool;
fn c_ext_set_log_print_cb(cb: WrappedLogPrintFn);
}
extern "C" fn rust_retro_ffi_log_print(level: LogLevel, msg: *const c_char) {
unsafe {
if let Some(cb) = CB_SINGLETON.handler.as_mut() {
cb.log_print(level, CStr::from_ptr(msg).to_string_lossy().as_ref());
}
}
}
#[allow(unused)]
pub trait Handler: Unpin + 'static {
fn _delegate_handler(&self) -> Option<&mut dyn Handler> { None }
@ -66,6 +79,9 @@ pub trait Handler: Unpin + 'static {
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 }
// -- environment-set callbacks (API extensions) --
fn log_print(&mut self, level: LogLevel, msg: &str) {}
}
#[derive(Default)]
@ -123,7 +139,7 @@ impl StaticCallbacks {
EnvCmd::GetInputDeviceCapabilities => Self::clone_into_void(data, &handler.get_input_device_capabilities()?)?,
// TODO EnvCmd::GetSensorInterface => {},
// TODO EnvCmd::GetCameraInterface => {},
// TODO EnvCmd::GetLogInterface => {},
EnvCmd::GetLogInterface => unsafe { c_ext_handle_get_log_interface(data as *mut LogCallback) },
// TODO EnvCmd::GetPerfInterface => {},
// TODO EnvCmd::GetLocationInterface => {},
EnvCmd::GetCoreAssetsDirectory => Self::path_into_void(data, handler.get_core_assets_directory()?)?,
@ -210,6 +226,7 @@ impl From<LibretroApi> for LibretroWrapper {
api.set_audio_sample_batch(StaticCallbacks::audio_sample_batch_cb);
api.set_input_poll(StaticCallbacks::input_poll_cb);
api.set_input_state(StaticCallbacks::input_state_cb);
unsafe { c_ext_set_log_print_cb(rust_retro_ffi_log_print); }
LibretroWrapper { api }
}
}