implement RETRO_ENVIRONMENT_SET_VARIABLES
This commit is contained in:
parent
0e3ba53eec
commit
871e0f799f
|
@ -5,7 +5,7 @@ extern crate sdl2;
|
|||
use rustro::retro;
|
||||
use rustro::retro::ffi::{GameGeometry, SystemInfo, SystemAvInfo};
|
||||
use rustro::retro::constants::{Input, DeviceIndex, JoypadButton, AnalogAxis, DeviceType};
|
||||
use rustro::retro::wrapper::LibretroWrapper;
|
||||
use rustro::retro::wrapper::{LibretroWrapper, VariableDescriptor};
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::io::Read;
|
||||
|
@ -280,6 +280,13 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_variables(&mut self, variables: &[VariableDescriptor]) -> bool {
|
||||
for v in variables {
|
||||
eprintln!("{:?}", v);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn get_libretro_path(&mut self) -> Option<PathBuf> {
|
||||
Some(self.core_path.clone())
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ pub trait Handler: Unpin + 'static {
|
|||
fn set_input_descriptors(&mut self, input_descriptors: &[InputDescriptor]) -> bool { false }
|
||||
fn set_hw_render(&mut self, hw_render_callback: HwRenderCallback) -> bool { false }
|
||||
fn get_variable(&mut self, key: &str) -> Option<String> { None }
|
||||
fn set_variables(&mut self, variables: &[Variable]) -> bool { false }
|
||||
fn set_variables(&mut self, variables: &[VariableDescriptor]) -> 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 }
|
||||
|
@ -80,6 +80,13 @@ pub trait Handler: Unpin + 'static {
|
|||
fn set_rumble_state(&mut self, port: c_uint, effect: RumbleEffect, strength: u16) -> bool { false }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableDescriptor {
|
||||
pub key: String,
|
||||
pub description: String,
|
||||
pub options: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct StaticCallbacks {
|
||||
handler: Option<Pin<&'static mut dyn Handler>>,
|
||||
|
@ -122,7 +129,7 @@ impl StaticCallbacks {
|
|||
}
|
||||
let handler = maybe_handler?;
|
||||
let parsed_cmd = cmd.try_into().ok();
|
||||
if parsed_cmd.is_none() {
|
||||
if cfg!(debug) && parsed_cmd.is_none() {
|
||||
eprintln!(
|
||||
"Unknown{} env cmd: {}",
|
||||
if cmd >= ENVIRONMENT_EXPERIMENTAL { ", experimental" } else { "" },
|
||||
|
@ -160,16 +167,25 @@ impl StaticCallbacks {
|
|||
EnvCmd::GetVariable => {
|
||||
let mut var = Self::from_void::<Variable>(data)?;
|
||||
let key = unsafe { CStr::from_ptr(var.key) }.to_str().ok()?;
|
||||
if !var.value.is_null() {
|
||||
let placeholder = unsafe { CStr::from_ptr(var.value) }.to_string_lossy();
|
||||
eprintln!("querying {}: {}", key, placeholder);
|
||||
}
|
||||
let value = handler.get_variable(key)?;
|
||||
// leaks memory.
|
||||
var.value = CString::new(value).ok()?.into_raw();
|
||||
true
|
||||
},
|
||||
// TODO EnvCmd::SetVariables => {},
|
||||
EnvCmd::SetVariables => {
|
||||
let mut var = data as *const Variable;
|
||||
let mut descriptors = Vec::new();
|
||||
while !unsafe { var.as_ref() }?.key.is_null() {
|
||||
let key = unsafe { CStr::from_ptr({ var.as_ref() }?.key) }.to_str().ok()?.to_string();
|
||||
let value = unsafe { CStr::from_ptr({ var.as_ref() }?.value) }.to_str().ok()?;
|
||||
let split: Vec<&str> = value.splitn(2, "; ").collect();
|
||||
let description = split.get(0)?.to_string();
|
||||
let options = split.get(1)?.split('|').map(String::from).collect();
|
||||
descriptors.push(VariableDescriptor { key, description, options });
|
||||
var = var.wrapping_add(1);
|
||||
}
|
||||
handler.set_variables(descriptors.as_ref())
|
||||
},
|
||||
EnvCmd::GetVariableUpdate => Self::clone_into_void(data, &handler.get_variable_update()?)?,
|
||||
EnvCmd::SetSupportNoGame => handler.set_support_no_game(*Self::from_void(data)?),
|
||||
EnvCmd::GetLibretroPath => Self::path_into_void(data, handler.get_libretro_path()?)?,
|
||||
|
@ -344,7 +360,7 @@ impl LibretroWrapper {
|
|||
pub fn disk_get_eject_state(&self) -> Option<bool> {
|
||||
self.disk_get_eject_state_cb.map(|f| unsafe { f() })
|
||||
}
|
||||
pub fn disk_set_eject_state(&self) -> Option<bool> {
|
||||
pub fn disk_set_eject_state(&self, ejected: bool) -> Option<bool> {
|
||||
self.disk_set_eject_state_cb.map(|f| unsafe { f(ejected) })
|
||||
}
|
||||
pub fn disk_get_image_index(&self) -> Option<c_uint> {
|
||||
|
|
Loading…
Reference in New Issue