Compare commits

...

3 Commits

6 changed files with 122 additions and 13 deletions

View File

@ -5,7 +5,7 @@ use ferretro::retro::wrapped_types::{ControllerDescription2, InputDescriptor2, I
use ferretro::retro::wrapper::LibretroWrapper;
use crate::sync::game::{SyncableGame, KnownGames, read_game_name, create_game};
use crate::emulator::libretro_memory_map::LibRetroMemoryMap;
use crate::emulator::libretro_memory_map;
use crate::emulator::metadata_reader::{GameInfo, get_game_info};
use std::ffi::CStr;
@ -50,7 +50,7 @@ pub struct MyEmulator {
gamepads: Vec<GameController>,
pressed_keys: Vec<Keycode>,
pub memory_map: Option<LibRetroMemoryMap>,
pub memory_map: libretro_memory_map::LibRetroMemoryMap,
synced_game: Option<Box<dyn SyncableGame>>,
}
@ -118,6 +118,8 @@ impl MyEmulator {
let pressed_keys = Vec::new();
let memory_map = libretro_memory_map::LibRetroMemoryMap::create_from_retro(&retro);
/*
let memory_map = std::default::Default::default();
let which_game = read_game_name("whatever");
@ -142,7 +144,7 @@ impl MyEmulator {
gamepad_subsys,
gamepads,
pressed_keys,
memory_map: None,
memory_map,
synced_game: None,
};
let mut pin_emu = Box::pin(emu);
@ -450,7 +452,7 @@ impl retro::wrapper::Handler for MyEmulator {
}
fn set_memory_maps(&mut self, ffi_memory_map: MemoryMap) -> bool {
self.memory_map = Some(LibRetroMemoryMap::create(&ffi_memory_map));
self.memory_map = libretro_memory_map::LibRetroMemoryMap::create_from_map(&ffi_memory_map);
true
}
}

View File

@ -1,5 +1,7 @@
use std::convert::TryFrom;
use ferretro::retro::ffi::{MemoryMap};
use ferretro::retro::loading::LibretroApi;
use crate::emulator::emulator::MyEmulator;
pub struct LibRetroMemoryMap {
regions: Vec<LibRetroMemoryRegion>,
@ -34,7 +36,7 @@ impl LibRetroMemoryMap {
None
}
pub fn create(memory_map: &MemoryMap) -> Self {
pub fn create_from_map(memory_map: &MemoryMap) -> Self {
let mut regions: Vec<LibRetroMemoryRegion> = Vec::new();
let num_descriptors = isize::try_from(memory_map.num_descriptors).unwrap();
for i in 0..num_descriptors {
@ -57,6 +59,21 @@ impl LibRetroMemoryMap {
regions: regions
}
}
pub fn create_from_retro(retro: &LibretroApi) -> Self{
let mut regions: Vec<LibRetroMemoryRegion> = Vec::new();
let memory = retro.get_memory(2 /*MEMORY_SYSTEM_RAM*/);
regions.push(LibRetroMemoryRegion {
start: 0,
end: memory.len(),
pointer: unsafe {memory.as_ptr() as *const std::ffi::c_void}
});
LibRetroMemoryMap {
regions: regions
}
}
}
struct LibRetroMemoryRegion {

View File

@ -44,13 +44,10 @@ pub fn main() -> failure::Fallible<()> {
fn attempt_to_start_sync(emu: &mut MyEmulator, comms_settings: CommunicationSettings) -> Result<(), failure::Error> {
match &emu.game_info {
Some(game_info) => match read_game_name(&game_info.game_name) {
Some(which_game) => match &emu.memory_map {
Some(memory_map) => {
let synced_game = create_game(which_game, comms_settings, memory_map);
emu.begin_sync(synced_game);
Ok(())
},
None => Err(format_err!("Memory map has not been set"))
Some(which_game) => {
let synced_game = create_game(which_game, comms_settings, &emu.memory_map);
emu.begin_sync(synced_game);
Ok(())
},
None => Err(format_err!("Unrecognized game {}", game_info.game_name))
},

View File

@ -1,4 +1,5 @@
use crate::sync::pokemon_rb::SyncedPokemonRedBlue;
use crate::sync::sonic2::SyncedSonic2;
use crate::sync::comms::CommunicationSettings;
use crate::emulator::libretro_memory_map::LibRetroMemoryMap;
@ -15,11 +16,14 @@ pub trait SyncableGame {
pub enum KnownGames {
PokemonRedBlue,
Sonic2,
}
pub fn read_game_name(name: &str) -> Option<KnownGames> {
match name {
"POKEMON BLUE" => Some(KnownGames::PokemonRedBlue),
"SONIC THE HEDGEHOG 2" => Some(KnownGames::Sonic2),
_ => None
}
}
@ -27,7 +31,8 @@ pub fn read_game_name(name: &str) -> Option<KnownGames> {
pub fn create_game(which_game: KnownGames, comms_settings: CommunicationSettings, memory_map: &LibRetroMemoryMap) -> Box<dyn SyncableGame> {
match which_game {
KnownGames::PokemonRedBlue => Box::from(SyncedPokemonRedBlue::create(comms_settings, memory_map))
KnownGames::PokemonRedBlue => Box::from(SyncedPokemonRedBlue::create(comms_settings, memory_map)),
KnownGames::Sonic2 => Box::from(SyncedSonic2::create(comms_settings, memory_map)),
}
}

View File

@ -1,4 +1,5 @@
pub mod pokemon_rb;
pub mod sonic2;
pub mod comms;
pub mod memory_slice_handle;
pub mod game;

87
src/sync/sonic2.rs Normal file
View File

@ -0,0 +1,87 @@
use std::default::Default;
use std::fmt::Display;
use crate::emulator::libretro_memory_map::LibRetroMemoryMap;
use serde::{Serialize, Deserialize};
use ferretro::retro::wrapper::LibretroWrapper; // want LibretroWrapper.api : LibretroApi.get_memory()
use crate::num::ToPrimitive;
use crate::sync::comms::Communication;
use crate::sync::comms::CommunicationSettings;
use crate::sync::memory_slice_handle::MemorySliceHandle;
use crate::sync::game::SyncableGame;
pub struct SyncedSonic2 {
memory_handles: Sonic2MemoryHandles<'static>,
comms: Communication<Sonic2Message>
}
#[derive(Serialize, Deserialize)]
pub struct Sonic2Message {
sonic_pos: Option<Vec<u8>>
}
impl From<&mut Sonic2MemoryHandles<'_>> for Sonic2Message {
fn from(src: &mut Sonic2MemoryHandles) -> Self {
Sonic2Message {
sonic_pos: src.sonic_pos.get_copy_if_changed_since_last_read()
}
}
}
struct Sonic2MemoryHandles<'a> {
sonic_pos: MemorySliceHandle<'a>,
tails_pos: MemorySliceHandle<'a>,
}
impl SyncableGame for SyncedSonic2 {
fn update_state(&mut self) {
/*
if let Some(d) = &self.memory_handles.sonic_pos.slice {
writeln!("sonic pos: {:?}", d)
}*/
}
fn send_state_messages(&mut self) -> Result<(), failure::Error>{
let message: Sonic2Message = (&mut self.memory_handles).into();
if !message.sonic_pos.is_none() {
self.comms.send(message)
}
else {
Ok(())
}
}
fn handle_inbound_messages(&mut self) -> Result<(), failure::Error>{
match self.comms.receive_if_any() {
Some(msg) => self.handle_message(msg),
None => Ok(())
}
}
}
impl Sonic2MemoryHandles<'_> {
pub fn create(memory_map: &LibRetroMemoryMap) -> Self {
Sonic2MemoryHandles {
sonic_pos: MemorySliceHandle::create(0xb008, 0x10, 0, memory_map),
tails_pos: MemorySliceHandle::create(0xb048, 0x10, 0, memory_map),
}
}
}
impl SyncedSonic2 {
pub fn create(comms_settings: CommunicationSettings, memory_map: &LibRetroMemoryMap) -> Self {
SyncedSonic2 {
memory_handles: Sonic2MemoryHandles::create(memory_map),
comms: Communication::new(comms_settings),
}
}
fn handle_message(&mut self, msg: Sonic2Message) -> Result<(), failure::Error> {
match msg.sonic_pos {
Some(src) => {
println!("message contains a new sonic pos. writing to tails. {:?}", &src);
self.memory_handles.tails_pos.write_to_slice(src)
}
None => Ok(())
}
}
}