implement RETRO_ENVIRONMENT_SET_VARIABLES
This commit is contained in:
		
							parent
							
								
									0e3ba53eec
								
							
						
					
					
						commit
						871e0f799f
					
				
					 2 changed files with 32 additions and 9 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue