wip: add lifetimes to memory stuff

This commit is contained in:
Vivian Lim 2019-12-24 15:46:34 -08:00
parent 063cb4374a
commit bb558096b2
3 changed files with 70 additions and 40 deletions

View File

@ -21,7 +21,7 @@ use sdl2::keyboard::Keycode;
use sdl2::rect::Rect;
use sdl2::render::WindowCanvas;
pub struct MyEmulator {
pub struct MyEmulator<'emu> {
retro: retro::wrapper::LibretroWrapper,
core_path: PathBuf,
sys_path: Option<PathBuf>,
@ -51,10 +51,12 @@ pub struct MyEmulator {
// memory
memory_map: Vec<MyMemoryMap>,
synced_pokemonrb: SyncedPokemonRedBlue,
synced_pokemonrb: SyncedPokemonRedBlue<'emu>,
_marker: std::marker::PhantomData<&'emu()>,
}
impl MyEmulator {
impl MyEmulator<'static> {
pub fn new(core_path: impl AsRef<Path>, sys_path: &Option<impl AsRef<Path>>) -> Pin<Box<Self>> {
let core_path = PathBuf::from(core_path.as_ref());
let lib = libloading::Library::new(&core_path).unwrap();
@ -121,6 +123,8 @@ impl MyEmulator {
let memory_map = Vec::new();
let synced_pokemonrb = std::default::Default::default();
let _marker = std::marker::PhantomData::default();
let emu = MyEmulator {
retro,
core_path,
@ -140,6 +144,7 @@ impl MyEmulator {
pressed_keys,
memory_map,
synced_pokemonrb,
_marker
};
let mut pin_emu = Box::pin(emu);
retro::wrapper::set_handler(pin_emu.as_mut());
@ -176,8 +181,8 @@ impl MyEmulator {
spf = 1.0 / 60.0;
}
let new_data = SyncedPokemonRedBlue::copy_from_emu(self);
std::mem::replace(&mut self.synced_pokemonrb, new_data);
self.synced_pokemonrb.update_from_emu(self);
println!("{}", self.synced_pokemonrb);
Duration::from_secs_f64(spf)
.checked_sub(frame_begin.elapsed())
@ -295,13 +300,13 @@ impl MyEmulator {
}
}
impl Drop for MyEmulator {
impl Drop for MyEmulator<'_> {
fn drop(&mut self) {
retro::wrapper::unset_handler();
}
}
impl retro::wrapper::Handler for MyEmulator {
impl retro::wrapper::Handler for MyEmulator<'static> {
fn libretro_core(&mut self) -> &mut LibretroWrapper {
&mut self.retro
}
@ -454,11 +459,10 @@ impl retro::wrapper::Handler for MyEmulator {
}
}
impl MemoryRw for MyEmulator {
fn peek_region<T>(&self, offset: usize, bank_switch: usize) -> Option<&T> {
let length = std::mem::size_of::<T>();
impl<'emu> MemoryRw<'emu> for MyEmulator<'emu> {
fn peek_region(&self, offset: usize, length: usize, bank_switch: usize) -> Option<&[u8]> {
match self.find_bank(offset, length, bank_switch) {
Some(ptr) => Some(unsafe { &*(ptr as *mut T) }),
Some(ptr) => Some(unsafe { std::slice::from_raw_parts::<'emu>(ptr, length) }),
None => None
}
}
@ -468,7 +472,7 @@ impl MemoryRw for MyEmulator {
}
}
struct MyMemoryMap {
struct MyMemoryMap<> {
start: usize,
end: usize,
pointer: *const std::ffi::c_void,

View File

@ -1,4 +1,4 @@
pub trait MemoryRw {
fn peek_region<T>(&self, offset: usize, bank_switch: usize) -> Option<&T>;
pub trait MemoryRw<'emu> {
fn peek_region(&self, offset: usize, length: usize, bank_switch: usize) -> Option<&[u8]>;
fn poke_region<T>(&mut self, offset: usize, data: T, bank_switch: usize);
}

View File

@ -5,8 +5,8 @@ use serde::{Serialize, Deserialize};
use ferretro::retro::wrapper::LibretroWrapper; // want LibretroWrapper.api : LibretroApi.get_memory()
#[derive(Default)]
pub struct SyncedPokemonRedBlue {
raw: Raw,
pub struct SyncedPokemonRedBlue<'emu> {
raw: Raw<'emu>,
battle_context: BattleContext,
}
@ -15,11 +15,29 @@ pub struct Message {
active_pkmn: Box<[u8]>
}
struct Raw {
active_pokemon_raw: [u8; 0x27],
struct Raw<'emu> {
active_pokemon_raw: EmulatorMemory<'emu>,
player_and_party: EmulatorMemory<'emu>,
pokemon_out: EmulatorMemory<'emu>,
}
player_and_party: [u8; 0x19e],
pokemon_out: u8,
struct EmulatorMemory<'emu> {
offset: usize,
length: usize,
bank_switch: usize,
data: Option<&'emu [u8]>,
}
impl<'emu> EmulatorMemory<'emu> {
pub fn get_data<T: MemoryRw<'emu>>(&mut self, emu: &'emu T) -> Option<&'emu [u8]> {
match self.data {
Some(_) => self.data,
None => {
self.data = emu.peek_region(self.offset, self.length, self.bank_switch);
self.data
}
}
}
}
struct BattleContext {
@ -27,25 +45,18 @@ struct BattleContext {
}
impl SyncedPokemonRedBlue {
pub fn copy_from_emu<T: MemoryRw>(emu: &T) -> SyncedPokemonRedBlue {
let raw = Raw {
active_pokemon_raw: *emu.peek_region(0xd009, 0).unwrap_or_else(|| &[0; 0x27]),
player_and_party: *emu.peek_region(0xd158, 0).unwrap_or_else(|| &[0; 0x19e]),
pokemon_out: *emu.peek_region(0xcc2f, 0).unwrap_or(&0),
};
impl<'emu> SyncedPokemonRedBlue<'emu> {
pub fn update_from_emu<T: MemoryRw<'emu>>(&mut self, emu: &'emu T) {
let battle_context = BattleContext {
active_pokemon: num::FromPrimitive::from_u8(raw.active_pokemon_raw[0xB]).unwrap_or(Pokemon::Unknown)
active_pokemon: match self.raw.active_pokemon_raw.get_data(emu) {
Some(d) => num::FromPrimitive::from_u8(d[0xB]).unwrap_or(Pokemon::Unknown),
None => Pokemon::Unknown
}
};
let result = SyncedPokemonRedBlue {
raw: raw,
battle_context: battle_context,
};
self.battle_context = battle_context;
println!("{}", result);
result
}
// pub fn get_message<'a>(&self) -> Message {
@ -56,12 +67,27 @@ impl SyncedPokemonRedBlue {
// }
}
impl Default for Raw {
impl<'emu> Default for Raw<'emu> {
fn default() -> Self {
Raw {
active_pokemon_raw: [0; 0x27],
player_and_party: [0; 0x19e],
pokemon_out: 0,
active_pokemon_raw: EmulatorMemory {
offset: 0xd009,
length: 0x27,
bank_switch: 0,
data: None,
},
player_and_party: EmulatorMemory {
offset: 0xd158,
length: 0x19e,
bank_switch: 0,
data: None,
},
pokemon_out: EmulatorMemory {
offset: 0xcc2f,
length: 0x1,
bank_switch: 0,
data: None,
},
}
}
}
@ -74,9 +100,9 @@ impl Default for BattleContext {
}
}
impl Display for SyncedPokemonRedBlue {
impl Display for SyncedPokemonRedBlue<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "active: pk {:?} {:?}", &self.battle_context.active_pokemon, &self.raw.active_pokemon_raw[0xB])
write!(f, "active: pk {:?}", &self.battle_context.active_pokemon)
}
}
#[derive(FromPrimitive, Debug)]