From 35b295daa2d20bc99b61bc2189e566d512642780 Mon Sep 17 00:00:00 2001 From: Jujstme Date: Sat, 23 Sep 2023 09:45:54 +0200 Subject: [PATCH] Added support for MEdnafen (SMS) and removed an unused leftover function --- src/emulator/sms/mednafen.rs | 30 ++++++++++++++++++++++++++++++ src/emulator/sms/mod.rs | 26 ++++++-------------------- 2 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 src/emulator/sms/mednafen.rs diff --git a/src/emulator/sms/mednafen.rs b/src/emulator/sms/mednafen.rs new file mode 100644 index 0000000..569359d --- /dev/null +++ b/src/emulator/sms/mednafen.rs @@ -0,0 +1,30 @@ +use crate::{file_format::pe, signature::Signature, Address, Address32, Process}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct State; + +impl State { + pub fn find_ram(&self, game: &Process) -> Option
{ + const SIG_32: Signature<8> = Signature::new("25 FF 1F 00 00 0F B6 80"); + const SIG_64: Signature<7> = Signature::new("25 FF 1F 00 00 88 90"); + + let main_module_range = super::PROCESS_NAMES + .iter() + .filter(|(_, state)| matches!(state, super::State::Mednafen(_))) + .find_map(|(name, _)| game.get_module_range(name).ok())?; + + let is_64_bit = + pe::MachineType::read(game, main_module_range.0) == Some(pe::MachineType::X86_64); + + let ptr = match is_64_bit { + true => SIG_64.scan_process_range(game, main_module_range)? + 8, + false => SIG_32.scan_process_range(game, main_module_range)? + 7, + }; + + Some(game.read::(ptr).ok()?.into()) + } + + pub const fn keep_alive(&self) -> bool { + true + } +} diff --git a/src/emulator/sms/mod.rs b/src/emulator/sms/mod.rs index a2f28bb..99206ee 100644 --- a/src/emulator/sms/mod.rs +++ b/src/emulator/sms/mod.rs @@ -5,6 +5,7 @@ use bytemuck::CheckedBitPattern; mod blastem; mod fusion; +mod mednafen; mod retroarch; /// A SEGA Master System / GameGear emulator that the auto splitter is attached to. @@ -55,6 +56,7 @@ impl Emulator { State::Retroarch(x) => x.find_ram(&self.process), State::Fusion(x) => x.find_ram(&self.process), State::BlastEm(x) => x.find_ram(&self.process), + State::Mednafen(x) => x.find_ram(&self.process), } { None => return false, something => something, @@ -65,6 +67,7 @@ impl Emulator { State::Retroarch(x) => x.keep_alive(&self.process), State::Fusion(x) => x.keep_alive(&self.process, &mut self.ram_base), State::BlastEm(x) => x.keep_alive(), + State::Mednafen(x) => x.keep_alive(), }; if success { @@ -75,28 +78,9 @@ impl Emulator { } } - /// Reads raw data from the emulated RAM ignoring all endianness settings - /// The same call, performed on two different emulators, can be different - /// due to the endianness used by the emulator. - /// - /// The offset provided must not be higher than `0xFFFF`, otherwise this - /// method will immediately return `Err()`. - /// - /// This call is meant to be used by experienced users. - pub fn read_ignoring_endianness(&self, offset: u32) -> Result { - if offset > 0xFFFF { - return Err(Error {}); - } - - let wram = self.ram_base.ok_or(Error {})?; - - self.process.read(wram + offset) - } - /// Reads any value from the emulated RAM. /// - /// The offset provided is meant to be the same used on the original, - /// big-endian system. + /// The offset provided is meant to be the same used on the original hardware. /// /// The SEGA Master System has 8KB of RAM, mapped from address /// `0xC000` to `0xDFFF`. @@ -120,10 +104,12 @@ pub enum State { Retroarch(retroarch::State), Fusion(fusion::State), BlastEm(blastem::State), + Mednafen(mednafen::State), } static PROCESS_NAMES: &[(&str, State)] = &[ ("retroarch.exe", State::Retroarch(retroarch::State::new())), ("Fusion.exe", State::Fusion(fusion::State::new())), ("blastem.exe", State::BlastEm(blastem::State)), + ("mednafen.exe", State::Mednafen(mednafen::State)), ];