basic serialization of memory wip

This commit is contained in:
Vivian Lim 2020-01-01 20:50:59 -08:00
parent ff18f2d382
commit 23f24e1f77
4 changed files with 123 additions and 29 deletions

24
Cargo.lock generated
View File

@ -153,6 +153,7 @@ dependencies = [
"sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -169,6 +170,11 @@ dependencies = [
"unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -465,6 +471,11 @@ name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sdl2"
version = "0.32.2"
@ -513,6 +524,16 @@ dependencies = [
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.8.0"
@ -648,6 +669,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
@ -681,11 +703,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum sdl2 0.32.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d051a07231e303f5f719da78cb6f7394f6d5b54f733aef5b0b447804a83edd7b"
"checksum sdl2-sys 0.32.6 (registry+https://github.com/rust-lang/crates.io-index)" = "34e71125077d297d57e4c1acfe8981b5bdfbf5a20e7b589abfdcb33bf1127f86"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3a3e93f5ad553c38b3301c8a0a0cec829a36783f6a0c467fc4bf553a5f5bf"
"checksum structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e"

View File

@ -19,5 +19,6 @@ crossbeam-channel = "^0.4"
structopt = "^0.3"
serde = { version = "1.0.104", features = ["derive"] }
serde_bytes = "0.11"
serde_json = "1.0.44"
[dev-dependencies]

View File

@ -49,8 +49,6 @@ pub struct MyEmulator {
pressed_keys: Vec<Keycode>,
// memory
memory_map: ReadWriteMemoryMap,
synced_pokemonrb: SyncedPokemonRedBlue,
}
@ -119,7 +117,7 @@ impl MyEmulator {
let pressed_keys = Vec::new();
let memory_map = std::default::Default::default();
let synced_pokemonrb = std::default::Default::default();
let synced_pokemonrb = SyncedPokemonRedBlue::create(memory_map);
let emu = MyEmulator {
retro,
@ -138,7 +136,6 @@ impl MyEmulator {
gamepad_subsys,
gamepads,
pressed_keys,
memory_map,
synced_pokemonrb,
};
let mut pin_emu = Box::pin(emu);
@ -176,7 +173,7 @@ impl MyEmulator {
spf = 1.0 / 60.0;
}
self.synced_pokemonrb.update_from_mem(&self.memory_map);
self.synced_pokemonrb.update_from_mem();
println!("{}", self.synced_pokemonrb);
Duration::from_secs_f64(spf)
@ -410,7 +407,7 @@ impl retro::wrapper::Handler for MyEmulator {
}
fn set_memory_maps(&mut self, memory_map: MemoryMap) -> bool {
self.memory_map.libretro_set_memory_maps(memory_map);
self.synced_pokemonrb.libretro_set_memory_maps(memory_map);
true
}
}

View File

@ -5,39 +5,46 @@ use serde::{Serialize, Deserialize};
use ferretro::retro::wrapper::LibretroWrapper; // want LibretroWrapper.api : LibretroApi.get_memory()
use crate::num::ToPrimitive;
#[derive(Default)]
pub struct SyncedPokemonRedBlue {
raw: Raw,
raw: Raw<'static>,
battle_context: BattleContext,
}
//#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize)]
pub struct Message {
active_pkmn: Box<[u8]>
active_pkmn: Option<Vec<u8>>
}
struct Raw {
active_pokemon_raw: EmulatorMemory,
player_and_party: EmulatorMemory,
pokemon_out: EmulatorMemory,
impl From<&Raw<'_>> for Message {
fn from(src: &Raw) -> Self {
Message {
active_pkmn: match &src.active_pokemon_raw.slice {
Some(m) => Some(m.to_vec()),
None => None
}
}
}
}
struct EmulatorMemory {
struct Raw<'a> {
active_pokemon_raw: EmulatorMemory<'a>,
player_and_party: EmulatorMemory<'a>,
pokemon_out: EmulatorMemory<'a>,
pub memory_map: ReadWriteMemoryMap,
}
struct EmulatorMemory<'a> {
offset: usize,
length: usize,
bank_switch: usize,
slice: Option<&'static mut [u8]>,
pub slice: Option<&'a mut [u8]>,
}
impl EmulatorMemory {
pub fn get_slice(&mut self, mem: &ReadWriteMemoryMap) -> &mut Option<&'static mut [u8]> {
match self.slice {
Some(_) => &mut self.slice,
None => {
self.slice = mem.get_slice_from_region(self.offset, self.length, self.bank_switch);
&mut self.slice
}
}
impl EmulatorMemory<'_> {
pub fn update_slice(&mut self, map: &ReadWriteMemoryMap) {
self.slice = map.get_slice_from_region(self.offset, self.length, self.bank_switch);
}
}
@ -47,9 +54,9 @@ struct BattleContext {
impl SyncedPokemonRedBlue {
pub fn update_from_mem(&mut self, mem: &ReadWriteMemoryMap) {
pub fn update_from_mem(&mut self) {
let battle_context = BattleContext {
active_pokemon: match self.raw.active_pokemon_raw.get_slice(mem) {
active_pokemon: match &self.raw.active_pokemon_raw.slice {
Some(d) => num::FromPrimitive::from_u8(d[0xB]).unwrap_or(Pokemon::Unknown),
None => Pokemon::Unknown
}
@ -76,8 +83,8 @@ impl SyncedPokemonRedBlue {
// }
}
impl Default for Raw {
fn default() -> Self {
impl Raw<'_> {
pub fn create(map: ReadWriteMemoryMap) -> Self {
Raw {
active_pokemon_raw: EmulatorMemory {
offset: 0xd009,
@ -97,6 +104,7 @@ impl Default for Raw {
bank_switch: 0,
slice: None,
},
memory_map: map
}
}
}
@ -114,6 +122,31 @@ impl Display for SyncedPokemonRedBlue {
write!(f, "active: pk {:?}", &self.battle_context.active_pokemon)
}
}
impl SyncedPokemonRedBlue {
pub fn create(map: ReadWriteMemoryMap) -> Self {
SyncedPokemonRedBlue {
raw: Raw::create(map),
battle_context: BattleContext::default(),
}
}
pub fn libretro_set_memory_maps(&mut self, libretro_memory_map: ferretro::retro::ffi::MemoryMap) {
self.raw.libretro_set_memory_maps(libretro_memory_map)
}
}
impl Raw<'_> {
pub fn libretro_set_memory_maps(&mut self, libretro_memory_map: ferretro::retro::ffi::MemoryMap) {
self.memory_map.libretro_set_memory_maps(libretro_memory_map);
// update our slices
self.active_pokemon_raw.update_slice(&self.memory_map);
self.player_and_party.update_slice(&self.memory_map);
self.pokemon_out.update_slice(&self.memory_map);
}
}
#[derive(FromPrimitive, ToPrimitive, Debug)]
enum Pokemon {
Unknown = 0x0,
@ -268,4 +301,43 @@ enum Pokemon {
Wigglytuff = 0x65,
Zapdos = 0x4B,
Zubat = 0x6B,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
fn build_message(em: &EmulatorMemory) -> Message {
Message {
active_pkmn: match &em.slice {
Some(m) => Some(m.to_vec()),
None => None
}
}
}
#[test]
fn serde_mem() -> Result<(), String> {
let mut data: [u8; 5] = [1, 2, 3, 4, 5];
let b: &mut [u8] = &mut data;
let slice = EmulatorMemory {
offset: 0,
length: 0,
bank_switch: 0,
slice: Some(b),
};
let message = build_message(&slice);
let serialized = serde_json::to_string(&message).unwrap();
println!("serialized data: {}", serialized);
let deserialized: Message = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized.active_pkmn.unwrap()[0], data[0]);
Ok(())
}
}