remove save states (they didnt work)
This commit is contained in:
parent
f1b3cabef9
commit
087bef7dc4
18 changed files with 18 additions and 696 deletions
|
@ -9,7 +9,6 @@ crate-type = ["cdylib", "rlib"]
|
|||
|
||||
[features]
|
||||
default = []
|
||||
savestate = []
|
||||
|
||||
[dependencies]
|
||||
gb-emu-lib = { path = "../lib" }
|
||||
|
|
|
@ -15,31 +15,8 @@ use std::sync::{
|
|||
};
|
||||
use ui::{Emulator, EmulatorRenderer};
|
||||
|
||||
#[cfg(feature = "savestate")]
|
||||
use gb_emu_lib::connect::CpuSaveState;
|
||||
|
||||
mod ui;
|
||||
|
||||
#[cfg(feature = "savestate")]
|
||||
#[derive(Default)]
|
||||
struct SaveStateParam {
|
||||
state: Arc<Mutex<Option<CpuSaveState<[u8; 4]>>>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "savestate")]
|
||||
impl PersistentField<'_, Option<CpuSaveState<[u8; 4]>>> for SaveStateParam {
|
||||
fn set(&self, new_value: Option<CpuSaveState<[u8; 4]>>) {
|
||||
*self.state.lock().unwrap() = new_value;
|
||||
}
|
||||
|
||||
fn map<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: Fn(&Option<CpuSaveState<[u8; 4]>>) -> R,
|
||||
{
|
||||
f(&self.state.lock().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct SramParam {
|
||||
state: Arc<RwLock<Vec<u8>>>,
|
||||
|
@ -64,9 +41,6 @@ impl PersistentField<'_, Vec<u8>> for SramParam {
|
|||
struct EmuParams {
|
||||
#[persist = "sram"]
|
||||
sram_save: SramParam,
|
||||
// #[cfg(feature = "savestate")]
|
||||
// #[persist = "save_state"]
|
||||
// last_save_state: SaveStateParam,
|
||||
}
|
||||
|
||||
struct EmuVars {
|
||||
|
@ -218,7 +192,6 @@ impl Plugin for GameboyEmu {
|
|||
} else {
|
||||
while context.next_event().is_some() {}
|
||||
}
|
||||
self.update_save_state();
|
||||
ProcessStatus::KeepAlive
|
||||
}
|
||||
|
||||
|
@ -266,19 +239,6 @@ impl Plugin for GameboyEmu {
|
|||
tx: None,
|
||||
};
|
||||
|
||||
#[cfg(feature = "savestate")]
|
||||
let mut emulator_core = if let Some(state) =
|
||||
self.params.last_save_state.state.lock().unwrap().take()
|
||||
{
|
||||
EmulatorCore::from_save_state(state, rom, receiver, window, output, serial_target)
|
||||
} else {
|
||||
let options = gb_emu_lib::Options::new(window, rom, output)
|
||||
.with_serial_target(serial_target)
|
||||
.force_no_save();
|
||||
|
||||
EmulatorCore::init(receiver, options)
|
||||
};
|
||||
#[cfg(not(feature = "savestate"))]
|
||||
let mut emulator_core = {
|
||||
let options = EmulatorOptions::new(window, rom, output)
|
||||
.with_serial_target(serial_target)
|
||||
|
@ -295,14 +255,12 @@ impl Plugin for GameboyEmu {
|
|||
emulator_core,
|
||||
serial_tx,
|
||||
});
|
||||
self.update_save_state();
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn deactivate(&mut self) {
|
||||
self.update_save_state();
|
||||
if let Some(ref mut vars) = self.vars {
|
||||
match vars.sender.send(EmulatorMessage::Stop) {
|
||||
Ok(_) => self.vars = None,
|
||||
|
@ -312,16 +270,6 @@ impl Plugin for GameboyEmu {
|
|||
}
|
||||
}
|
||||
|
||||
impl GameboyEmu {
|
||||
fn update_save_state(&mut self) {
|
||||
#[cfg(feature = "savestate")]
|
||||
if let Some(ref mut vars) = self.vars {
|
||||
*self.params.last_save_state.state.lock().unwrap() =
|
||||
Some(vars.emulator_core.get_save_state());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Vst3Plugin for GameboyEmu {
|
||||
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ use std::sync::{Arc, Mutex, RwLock};
|
|||
pub use crate::processor::memory::mmio::gpu::Colour;
|
||||
pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState};
|
||||
pub use crate::processor::memory::mmio::serial::SerialTarget;
|
||||
pub use crate::processor::CpuSaveState;
|
||||
pub use crate::{HEIGHT, WIDTH};
|
||||
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
};
|
||||
use connect::{
|
||||
AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorCoreTrait, EmulatorMessage,
|
||||
EmulatorOptions, NoCamera, PocketCamera, Renderer, RomFile, SerialTarget, SramType,
|
||||
EmulatorOptions, PocketCamera, Renderer, RomFile, SramType,
|
||||
};
|
||||
use processor::{
|
||||
memory::{
|
||||
|
@ -14,7 +14,7 @@ use processor::{
|
|||
rom::{sram_save::SaveDataLocation, CgbRomType},
|
||||
OutputTargets, Rom,
|
||||
},
|
||||
Cpu, CpuSaveState,
|
||||
Cpu,
|
||||
};
|
||||
use std::{
|
||||
fs::{self},
|
||||
|
@ -186,13 +186,6 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
pub fn get_save_state(&self) -> CpuSaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
CpuSaveState::create(&self.cpu)
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColourFormat, R, C> EmulatorCoreTrait for EmulatorCore<ColourFormat, R, C>
|
||||
|
@ -254,41 +247,3 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> EmulatorCore<ColourFormat, R, NoCamera>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
pub fn from_save_state(
|
||||
state: CpuSaveState<ColourFormat, R>,
|
||||
rom: RomFile,
|
||||
receiver: Receiver<EmulatorMessage>,
|
||||
window: R,
|
||||
output: AudioOutput,
|
||||
serial_target: SerialTarget,
|
||||
) -> Self {
|
||||
let data = match rom {
|
||||
RomFile::Path(path) => match fs::read(path) {
|
||||
Ok(data) => data,
|
||||
Err(e) => {
|
||||
println!("Error reading ROM: {e}");
|
||||
exit(1);
|
||||
}
|
||||
},
|
||||
RomFile::Raw(data) => data,
|
||||
};
|
||||
Self {
|
||||
receiver,
|
||||
cpu: Cpu::from_save_state(
|
||||
state,
|
||||
data,
|
||||
window,
|
||||
output,
|
||||
serial_target,
|
||||
Arc::new(Mutex::new(CameraWrapper::new(NoCamera::default()))),
|
||||
),
|
||||
spooky: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,10 @@ pub use self::rom::Rom;
|
|||
use self::{
|
||||
addresses::{Address, AddressMarker, CgbIoAddress, IoAddress},
|
||||
mmio::{
|
||||
apu::ApuSaveState,
|
||||
cgb::{DoubleSpeed, Infrared, VramDma},
|
||||
gpu::{Colour, GpuSaveState},
|
||||
serial::SerialSaveState,
|
||||
gpu::Colour,
|
||||
Apu, Gpu, Joypad, OamDma, Serial, Timer,
|
||||
},
|
||||
rom::RomSaveState,
|
||||
};
|
||||
use crate::{
|
||||
connect::{AudioOutput, CameraWrapperRef, JoypadState, PocketCamera, Renderer, SerialTarget},
|
||||
|
@ -112,56 +109,6 @@ where
|
|||
cgb_peripherals: Option<CgbPeripherals>,
|
||||
}
|
||||
|
||||
#[serde_with::serde_as]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct MemorySaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
rom: RomSaveState,
|
||||
ram: Wram,
|
||||
#[serde_as(as = "[_; 128]")]
|
||||
cpu_ram: [u8; 128],
|
||||
pub(super) interrupts: Interrupts,
|
||||
pub(super) ime: bool,
|
||||
pub(super) ime_scheduled: u8,
|
||||
pub(super) user_mode: bool,
|
||||
oam_dma: OamDma,
|
||||
joypad: Joypad,
|
||||
gpu: GpuSaveState<ColourFormat, R>,
|
||||
apu: ApuSaveState,
|
||||
serial: SerialSaveState,
|
||||
timers: Timer,
|
||||
cgb_peripherals: Option<CgbPeripherals>,
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> MemorySaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
// C: PocketCamera + Send + 'static,
|
||||
{
|
||||
pub fn create<C: PocketCamera + Send + 'static>(memory: &Memory<ColourFormat, R, C>) -> Self {
|
||||
Self {
|
||||
rom: RomSaveState::create(&memory.rom),
|
||||
ram: memory.ram.clone(),
|
||||
cpu_ram: memory.cpu_ram,
|
||||
interrupts: memory.interrupts,
|
||||
ime: memory.ime,
|
||||
ime_scheduled: memory.ime_scheduled,
|
||||
user_mode: memory.user_mode,
|
||||
oam_dma: memory.oam_dma,
|
||||
joypad: memory.joypad,
|
||||
gpu: GpuSaveState::create(&memory.gpu),
|
||||
apu: ApuSaveState::create(&memory.apu),
|
||||
serial: SerialSaveState::create(&memory.serial),
|
||||
timers: memory.timers,
|
||||
cgb_peripherals: memory.cgb_peripherals,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct OutputTargets<ColourFormat, R, C>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
|
@ -455,34 +402,6 @@ where
|
|||
pub fn replace_output(&mut self, new: AudioOutput) {
|
||||
self.apu.replace_output(new);
|
||||
}
|
||||
|
||||
pub(crate) fn from_save_state(
|
||||
state: MemorySaveState<ColourFormat, R>,
|
||||
data: Vec<u8>,
|
||||
window: R,
|
||||
output: AudioOutput,
|
||||
serial_target: SerialTarget,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bootrom: None,
|
||||
rom: Rom::from_save_state(state.rom, data, camera.clone()),
|
||||
ram: state.ram,
|
||||
cpu_ram: state.cpu_ram,
|
||||
interrupts: state.interrupts,
|
||||
ime: state.ime,
|
||||
ime_scheduled: state.ime_scheduled,
|
||||
user_mode: state.user_mode,
|
||||
oam_dma: state.oam_dma,
|
||||
joypad: state.joypad,
|
||||
gpu: Gpu::from_save_state(state.gpu, window, None),
|
||||
apu: Apu::from_save_state(state.apu, output),
|
||||
serial: Serial::from_save_state(state.serial, serial_target),
|
||||
timers: state.timers,
|
||||
camera,
|
||||
cgb_peripherals: state.cgb_peripherals,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColourFormat, R, C> Cpu<ColourFormat, R, C>
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
};
|
||||
use futures::executor;
|
||||
use itertools::izip;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod channels;
|
||||
mod downsampler;
|
||||
|
@ -46,27 +45,6 @@ pub struct Apu {
|
|||
output: AudioOutput,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ApuSaveState {
|
||||
apu_enable: bool,
|
||||
channels: Channels,
|
||||
vin: VinEnable,
|
||||
mixer: Mixer,
|
||||
div_apu: u8,
|
||||
}
|
||||
|
||||
impl ApuSaveState {
|
||||
pub fn create(apu: &Apu) -> Self {
|
||||
Self {
|
||||
apu_enable: apu.apu_enable,
|
||||
channels: apu.channels,
|
||||
vin: apu.vin,
|
||||
mixer: apu.mixer,
|
||||
div_apu: apu.div_apu,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Apu {
|
||||
pub fn new(output: AudioOutput) -> Self {
|
||||
Self {
|
||||
|
@ -80,18 +58,6 @@ impl Apu {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: ApuSaveState, output: AudioOutput) -> Self {
|
||||
Self {
|
||||
apu_enable: state.apu_enable,
|
||||
channels: state.channels,
|
||||
vin: state.vin,
|
||||
mixer: state.mixer,
|
||||
div_apu: state.div_apu,
|
||||
converter: Downsampler::new(output.sample_rate, output.downsample_type),
|
||||
output,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replace_output(&mut self, new: AudioOutput) {
|
||||
self.converter = Downsampler::new(new.sample_rate, new.downsample_type);
|
||||
self.output = new;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
pub(crate) use self::types::DrawMode;
|
||||
use self::{
|
||||
cgb::CgbData,
|
||||
|
@ -15,7 +13,6 @@ use crate::{
|
|||
util::{clear_bit, get_bit},
|
||||
HEIGHT, WIDTH,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use types::Colour;
|
||||
|
||||
mod addresses;
|
||||
|
@ -56,70 +53,6 @@ where
|
|||
cgb_data: Option<CgbData>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GpuSaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
buffer: Vec<ColourFormat>,
|
||||
vram: Vram,
|
||||
oam: Oam,
|
||||
is_bg_zero: Vec<bool>,
|
||||
is_bg_priority: Vec<bool>,
|
||||
lcdc: Lcdc,
|
||||
stat: Stat,
|
||||
mode_clock: usize,
|
||||
scanline: u8,
|
||||
lyc: u8,
|
||||
window_lc: u8,
|
||||
has_window_been_enabled: bool,
|
||||
bg_palette: Palette,
|
||||
obj_palette_0: Palette,
|
||||
obj_palette_1: Palette,
|
||||
scx: u8,
|
||||
scy: u8,
|
||||
wx: u8,
|
||||
wy: u8,
|
||||
prev_stat: bool,
|
||||
cgb_data: Option<CgbData>,
|
||||
#[serde(skip)]
|
||||
spooky: PhantomData<R>,
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> GpuSaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
pub fn create(gpu: &Gpu<ColourFormat, R>) -> Self {
|
||||
Self {
|
||||
buffer: gpu.buffer.clone(),
|
||||
vram: gpu.vram.clone(),
|
||||
oam: gpu.oam,
|
||||
is_bg_zero: gpu.is_bg_zero.clone(),
|
||||
is_bg_priority: gpu.is_bg_priority.clone(),
|
||||
lcdc: gpu.lcdc,
|
||||
stat: gpu.stat,
|
||||
mode_clock: gpu.mode_clock,
|
||||
scanline: gpu.scanline,
|
||||
lyc: gpu.lyc,
|
||||
window_lc: gpu.window_lc,
|
||||
has_window_been_enabled: gpu.has_window_been_enabled,
|
||||
bg_palette: gpu.bg_palette,
|
||||
obj_palette_0: gpu.obj_palette_0,
|
||||
obj_palette_1: gpu.obj_palette_1,
|
||||
scx: gpu.scx,
|
||||
scy: gpu.scy,
|
||||
wx: gpu.wx,
|
||||
wy: gpu.wy,
|
||||
prev_stat: gpu.prev_stat,
|
||||
cgb_data: gpu.cgb_data,
|
||||
spooky: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> Gpu<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
|
@ -157,47 +90,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_save_state(
|
||||
state: GpuSaveState<ColourFormat, R>,
|
||||
window: R,
|
||||
tile_window_renderer: Option<R>,
|
||||
) -> Self {
|
||||
let tile_window = if let Some(tile_window_renderer) = tile_window_renderer {
|
||||
Some(TileWindow::new(
|
||||
tile_window_renderer,
|
||||
state.cgb_data.is_some(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Self {
|
||||
buffer: state.buffer,
|
||||
vram: state.vram,
|
||||
oam: state.oam,
|
||||
window,
|
||||
is_bg_zero: state.is_bg_zero,
|
||||
is_bg_priority: state.is_bg_priority,
|
||||
lcdc: state.lcdc,
|
||||
stat: state.stat,
|
||||
mode_clock: state.mode_clock,
|
||||
scanline: state.scanline,
|
||||
lyc: state.lyc,
|
||||
tile_window,
|
||||
window_lc: state.window_lc,
|
||||
has_window_been_enabled: state.has_window_been_enabled,
|
||||
bg_palette: state.bg_palette,
|
||||
obj_palette_0: state.obj_palette_0,
|
||||
obj_palette_1: state.obj_palette_1,
|
||||
scx: state.scx,
|
||||
scy: state.scy,
|
||||
wx: state.wx,
|
||||
wy: state.wy,
|
||||
prev_stat: state.prev_stat,
|
||||
cgb_data: state.cgb_data,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_mode(&self) -> DrawMode {
|
||||
self.stat.mode
|
||||
}
|
||||
|
|
|
@ -111,31 +111,6 @@ pub struct Serial {
|
|||
clock_inc: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SerialSaveState {
|
||||
byte: u8,
|
||||
output_byte: u8,
|
||||
input_byte: InputByte,
|
||||
bits_remaining: u8,
|
||||
control: SerialControl,
|
||||
#[cfg(feature = "clocked-serial")]
|
||||
clock_inc: usize,
|
||||
}
|
||||
|
||||
impl SerialSaveState {
|
||||
pub fn create(serial: &Serial) -> Self {
|
||||
Self {
|
||||
byte: serial.byte,
|
||||
output_byte: serial.output_byte,
|
||||
input_byte: serial.input_byte,
|
||||
bits_remaining: serial.bits_remaining,
|
||||
control: serial.control,
|
||||
#[cfg(feature = "clocked-serial")]
|
||||
clock_inc: serial.clock_inc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serial {
|
||||
pub fn new(target: SerialTarget) -> Self {
|
||||
Self {
|
||||
|
@ -150,19 +125,6 @@ impl Serial {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: SerialSaveState, target: SerialTarget) -> Self {
|
||||
Self {
|
||||
byte: state.byte,
|
||||
output_byte: state.output_byte,
|
||||
input_byte: state.input_byte,
|
||||
bits_remaining: state.bits_remaining,
|
||||
control: state.control,
|
||||
target,
|
||||
#[cfg(feature = "clocked-serial")]
|
||||
clock_inc: state.clock_inc,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_connected(&self) -> bool {
|
||||
!matches!(&self.target, SerialTarget::None)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use self::{
|
||||
mbcs::{
|
||||
Mbc, Mbc1, Mbc1SaveState, Mbc2, Mbc2SaveState, Mbc3, Mbc3SaveState, Mbc5, Mbc5SaveState,
|
||||
None, PocketCamera, PocketCameraSaveState,
|
||||
},
|
||||
mbcs::{Mbc, Mbc1, Mbc2, Mbc3, Mbc5, None, PocketCamera},
|
||||
sram_save::SaveDataLocation,
|
||||
};
|
||||
use crate::connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait};
|
||||
|
@ -31,50 +28,6 @@ where
|
|||
spooky: PhantomData<C>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct RomSaveState {
|
||||
title: String,
|
||||
mbc: MbcSaveState,
|
||||
}
|
||||
|
||||
impl RomSaveState {
|
||||
pub fn create<C: PocketCameraTrait>(rom: &Rom<C>) -> Self {
|
||||
Self {
|
||||
title: rom.title.clone(),
|
||||
mbc: rom.mbc.get_save_state(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum MbcSaveState {
|
||||
Mbc1(Mbc1SaveState),
|
||||
Mbc2(Mbc2SaveState),
|
||||
Mbc3(Mbc3SaveState),
|
||||
Mbc5(Mbc5SaveState),
|
||||
PocketCamera(PocketCameraSaveState),
|
||||
None,
|
||||
}
|
||||
|
||||
impl MbcSaveState {
|
||||
fn get_mbc<C: PocketCameraTrait + Send + 'static>(
|
||||
self,
|
||||
data: Vec<u8>,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> Box<dyn Mbc> {
|
||||
match self {
|
||||
MbcSaveState::Mbc1(state) => Box::new(Mbc1::from_save_state(state, data)),
|
||||
MbcSaveState::Mbc2(state) => Box::new(Mbc2::from_save_state(state, data)),
|
||||
MbcSaveState::Mbc3(state) => Box::new(Mbc3::from_save_state(state, data)),
|
||||
MbcSaveState::Mbc5(state) => Box::new(Mbc5::from_save_state(state, data)),
|
||||
MbcSaveState::None => Box::new(None::init(data)),
|
||||
MbcSaveState::PocketCamera(state) => {
|
||||
Box::new(PocketCamera::from_save_state(state, data, camera))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Rom<C>
|
||||
where
|
||||
C: PocketCameraTrait + Send + 'static,
|
||||
|
@ -135,20 +88,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_save_state(
|
||||
state: RomSaveState,
|
||||
data: Vec<u8>,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> Self {
|
||||
let rom_type = get_cgb_rom_type(data[0x143]);
|
||||
Self {
|
||||
title: state.title,
|
||||
mbc: state.mbc.get_mbc(data, camera),
|
||||
rom_type,
|
||||
spooky: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_title(&self) -> &String {
|
||||
&self.title
|
||||
}
|
||||
|
|
|
@ -6,14 +6,12 @@ mod mbc3;
|
|||
mod mbc5;
|
||||
mod none;
|
||||
mod pocketcamera;
|
||||
pub use mbc1::{Mbc1, Mbc1SaveState};
|
||||
pub use mbc2::{Mbc2, Mbc2SaveState};
|
||||
pub use mbc3::{Mbc3, Mbc3SaveState};
|
||||
pub use mbc5::{Mbc5, Mbc5SaveState};
|
||||
pub use mbc1::Mbc1;
|
||||
pub use mbc2::Mbc2;
|
||||
pub use mbc3::Mbc3;
|
||||
pub use mbc5::Mbc5;
|
||||
pub use none::None;
|
||||
pub use pocketcamera::{PocketCamera, PocketCameraSaveState};
|
||||
|
||||
use super::MbcSaveState;
|
||||
pub use pocketcamera::PocketCamera;
|
||||
|
||||
pub(super) const KB: usize = 1024;
|
||||
const ROM_BANK_SIZE: usize = 16 * KB;
|
||||
|
@ -27,7 +25,6 @@ pub(super) trait Mbc: Send {
|
|||
fn set(&mut self, address: RomAddress, data: u8);
|
||||
fn set_ram(&mut self, address: CartRamAddress, data: u8);
|
||||
fn mbc_type(&self) -> String;
|
||||
fn get_save_state(&self) -> MbcSaveState;
|
||||
fn is_rumbling(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
|
||||
use crate::processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::{
|
||||
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
|
||||
MbcSaveState,
|
||||
},
|
||||
rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -25,17 +22,6 @@ pub struct Mbc1 {
|
|||
bank_mode: BankingMode,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Mbc1SaveState {
|
||||
rom_len: usize,
|
||||
rom_bank: u8,
|
||||
ram_enabled: bool,
|
||||
ram: Option<SramSaveState>,
|
||||
ram_bank: u8,
|
||||
upper_banks: u8,
|
||||
bank_mode: BankingMode,
|
||||
}
|
||||
|
||||
impl Mbc1 {
|
||||
pub fn init(
|
||||
data: Vec<u8>,
|
||||
|
@ -86,19 +72,6 @@ impl Mbc1 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: Mbc1SaveState, data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
data,
|
||||
rom_len: state.rom_len,
|
||||
rom_bank: state.rom_bank,
|
||||
ram_enabled: state.ram_enabled,
|
||||
ram: state.ram.map(MaybeBufferedSram::from_save_state),
|
||||
ram_bank: state.ram_bank,
|
||||
upper_banks: state.upper_banks,
|
||||
bank_mode: state.bank_mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mbc for Mbc1 {
|
||||
|
@ -165,16 +138,4 @@ impl Mbc for Mbc1 {
|
|||
ram.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::Mbc1(Mbc1SaveState {
|
||||
rom_len: self.rom_len,
|
||||
rom_bank: self.rom_bank,
|
||||
ram_enabled: self.ram_enabled,
|
||||
ram: self.ram.as_ref().map(SramSaveState::create),
|
||||
ram_bank: self.ram_bank,
|
||||
upper_banks: self.upper_banks,
|
||||
bank_mode: self.bank_mode,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
use super::{rom_banks, Mbc, ROM_BANK_SIZE};
|
||||
use crate::processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::{
|
||||
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
|
||||
MbcSaveState,
|
||||
},
|
||||
rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{rom_banks, Mbc, ROM_BANK_SIZE};
|
||||
|
||||
pub struct Mbc2 {
|
||||
data: Vec<u8>,
|
||||
|
@ -17,14 +12,6 @@ pub struct Mbc2 {
|
|||
ram_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Mbc2SaveState {
|
||||
rom_len: usize,
|
||||
rom_bank: u8,
|
||||
ram: SramSaveState,
|
||||
ram_enabled: bool,
|
||||
}
|
||||
|
||||
impl Mbc2 {
|
||||
pub fn init(data: Vec<u8>, rom_size: u8, save_file: Option<SaveDataLocation>) -> Self {
|
||||
let rom_len = rom_banks(rom_size) * ROM_BANK_SIZE;
|
||||
|
@ -38,16 +25,6 @@ impl Mbc2 {
|
|||
ram_enabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: Mbc2SaveState, data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
data,
|
||||
rom_len: state.rom_len,
|
||||
rom_bank: state.rom_bank,
|
||||
ram: MaybeBufferedSram::from_save_state(state.ram),
|
||||
ram_enabled: state.ram_enabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mbc for Mbc2 {
|
||||
|
@ -97,13 +74,4 @@ impl Mbc for Mbc2 {
|
|||
fn flush(&mut self) {
|
||||
self.ram.flush();
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::Mbc2(Mbc2SaveState {
|
||||
rom_len: self.rom_len,
|
||||
rom_bank: self.rom_bank,
|
||||
ram: SramSaveState::create(&self.ram),
|
||||
ram_enabled: self.ram_enabled,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,7 @@ use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
|
|||
use crate::{
|
||||
processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::{
|
||||
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
|
||||
MbcSaveState,
|
||||
},
|
||||
rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
},
|
||||
util::set_or_clear_bit,
|
||||
};
|
||||
|
@ -95,16 +92,6 @@ pub struct Mbc3 {
|
|||
// TODO - save/load rtc!!
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Mbc3SaveState {
|
||||
rom_bank: u8,
|
||||
rom_size: usize,
|
||||
ram: Option<SramSaveState>,
|
||||
ram_bank: RamBank,
|
||||
ram_size: usize,
|
||||
ram_enabled: bool,
|
||||
}
|
||||
|
||||
impl Mbc3 {
|
||||
pub fn init(
|
||||
data: Vec<u8>,
|
||||
|
@ -139,20 +126,6 @@ impl Mbc3 {
|
|||
fn get_ram_addr(&self, address: CartRamAddress, ram_bank: usize) -> usize {
|
||||
((address.get_local() as usize) + (RAM_BANK_SIZE * ram_bank)) % self.ram_size
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: Mbc3SaveState, data: Vec<u8>) -> Self {
|
||||
// TODO - FIX RTC!!!
|
||||
Self {
|
||||
data,
|
||||
rom_bank: state.rom_bank,
|
||||
rom_size: state.rom_size,
|
||||
ram: state.ram.map(MaybeBufferedSram::from_save_state),
|
||||
ram_bank: state.ram_bank,
|
||||
ram_size: state.ram_size,
|
||||
ram_enabled: state.ram_enabled,
|
||||
rtc: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mbc for Mbc3 {
|
||||
|
@ -255,15 +228,4 @@ impl Mbc for Mbc3 {
|
|||
ram.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::Mbc3(Mbc3SaveState {
|
||||
rom_bank: self.rom_bank,
|
||||
rom_size: self.rom_size,
|
||||
ram: self.ram.as_ref().map(SramSaveState::create),
|
||||
ram_bank: self.ram_bank,
|
||||
ram_size: self.ram_size,
|
||||
ram_enabled: self.ram_enabled,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
use crate::{
|
||||
processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::{
|
||||
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
|
||||
MbcSaveState,
|
||||
},
|
||||
rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
},
|
||||
util::get_bit,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
|
||||
|
||||
|
@ -24,18 +20,6 @@ pub struct Mbc5 {
|
|||
is_rumbling: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Mbc5SaveState {
|
||||
rom_bank: u16,
|
||||
rom_size: usize,
|
||||
ram: Option<SramSaveState>,
|
||||
ram_bank: u8,
|
||||
ram_size: usize,
|
||||
ram_enabled: bool,
|
||||
rumble: bool,
|
||||
is_rumbling: bool,
|
||||
}
|
||||
|
||||
impl Mbc5 {
|
||||
pub fn init(
|
||||
data: Vec<u8>,
|
||||
|
@ -71,20 +55,6 @@ impl Mbc5 {
|
|||
fn get_ram_addr(&self, address: CartRamAddress) -> usize {
|
||||
((address.get_local() as usize) + (RAM_BANK_SIZE * self.ram_bank as usize)) % self.ram_size
|
||||
}
|
||||
|
||||
pub fn from_save_state(state: Mbc5SaveState, data: Vec<u8>) -> Self {
|
||||
Self {
|
||||
data,
|
||||
rom_bank: state.rom_bank,
|
||||
rom_size: state.rom_size,
|
||||
ram: state.ram.map(MaybeBufferedSram::from_save_state),
|
||||
ram_bank: state.ram_bank,
|
||||
ram_size: state.ram_size,
|
||||
ram_enabled: state.ram_enabled,
|
||||
rumble: state.rumble,
|
||||
is_rumbling: state.is_rumbling,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mbc for Mbc5 {
|
||||
|
@ -157,17 +127,4 @@ impl Mbc for Mbc5 {
|
|||
ram.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::Mbc5(Mbc5SaveState {
|
||||
rom_bank: self.rom_bank,
|
||||
rom_size: self.rom_size,
|
||||
ram: self.ram.as_ref().map(SramSaveState::create),
|
||||
ram_bank: self.ram_bank,
|
||||
ram_size: self.ram_size,
|
||||
ram_enabled: self.ram_enabled,
|
||||
rumble: self.rumble,
|
||||
is_rumbling: self.is_rumbling,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
use super::Mbc;
|
||||
use crate::processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::MbcSaveState,
|
||||
};
|
||||
use crate::processor::memory::addresses::{AddressMarker, CartRamAddress, RomAddress};
|
||||
|
||||
pub struct None {
|
||||
data: Vec<u8>,
|
||||
|
@ -30,8 +27,4 @@ impl Mbc for None {
|
|||
fn mbc_type(&self) -> String {
|
||||
String::from("None")
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,9 @@ use crate::{
|
|||
connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait},
|
||||
processor::memory::{
|
||||
addresses::{AddressMarker, CartRamAddress, RomAddress},
|
||||
rom::{
|
||||
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
MbcSaveState,
|
||||
},
|
||||
rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
enum RamBank {
|
||||
Ram(u8),
|
||||
|
@ -32,9 +28,6 @@ where
|
|||
camera_ram: [u8; 53],
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct PocketCameraSaveState;
|
||||
|
||||
impl<C> PocketCamera<C>
|
||||
where
|
||||
C: PocketCameraTrait,
|
||||
|
@ -76,14 +69,6 @@ where
|
|||
((address.get_local() as usize) + (RAM_BANK_SIZE * bank as usize)) % self.ram_size
|
||||
}
|
||||
|
||||
pub(crate) fn from_save_state(
|
||||
_state: PocketCameraSaveState,
|
||||
_data: Vec<u8>,
|
||||
_camera: CameraWrapperRef<C>,
|
||||
) -> Self {
|
||||
todo!();
|
||||
}
|
||||
|
||||
fn get_cam_reg(&self, address: CartRamAddress) -> u8 {
|
||||
match address.inner() {
|
||||
0xA000 => {
|
||||
|
@ -202,8 +187,4 @@ where
|
|||
ram.flush();
|
||||
}
|
||||
}
|
||||
|
||||
fn get_save_state(&self) -> MbcSaveState {
|
||||
MbcSaveState::PocketCamera(PocketCameraSaveState)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fs::{File, OpenOptions},
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
|
@ -28,10 +27,6 @@ impl MaybeBufferedSram {
|
|||
None => Self::Unbuffered(UnbufferedSram::new(length)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_save_state(state: SramSaveState) -> Self {
|
||||
Self::Unbuffered(UnbufferedSram::new(state.length))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct UnbufferedSram {
|
||||
|
@ -228,17 +223,6 @@ impl BufferedSramTrait for MaybeBufferedSram {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub(crate) struct SramSaveState {
|
||||
length: usize,
|
||||
}
|
||||
|
||||
impl SramSaveState {
|
||||
pub fn create(sram: &MaybeBufferedSram) -> Self {
|
||||
Self { length: sram.len() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MaybeBufferedSram {
|
||||
fn drop(&mut self) {
|
||||
self.flush();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use self::memory::{mmio::gpu::Colour, Interrupt, Memory, MemorySaveState};
|
||||
use crate::connect::{AudioOutput, CameraWrapperRef, PocketCamera, Renderer, SerialTarget};
|
||||
use self::memory::{mmio::gpu::Colour, Interrupt, Memory};
|
||||
use crate::connect::{PocketCamera, Renderer};
|
||||
|
||||
mod instructions;
|
||||
pub mod memory;
|
||||
|
@ -36,39 +36,6 @@ where
|
|||
pub(crate) is_skipping: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CpuSaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
memory: MemorySaveState<ColourFormat, R>,
|
||||
reg: Registers,
|
||||
last_instruction: u8,
|
||||
last_instruction_addr: u16,
|
||||
halted: bool,
|
||||
should_halt_bug: bool,
|
||||
cycle_count: usize,
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> CpuSaveState<ColourFormat, R>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
R: Renderer<ColourFormat>,
|
||||
{
|
||||
pub fn create<C: PocketCamera + Send + 'static>(cpu: &Cpu<ColourFormat, R, C>) -> Self {
|
||||
Self {
|
||||
memory: MemorySaveState::create(&cpu.memory),
|
||||
reg: cpu.reg,
|
||||
last_instruction: cpu.last_instruction,
|
||||
last_instruction_addr: cpu.last_instruction_addr,
|
||||
halted: cpu.halted,
|
||||
should_halt_bug: cpu.should_halt_bug,
|
||||
cycle_count: cpu.cycle_count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<ColourFormat, R, C> Cpu<ColourFormat, R, C>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
|
@ -178,33 +145,6 @@ where
|
|||
self.reg.pc = addr;
|
||||
self.memory.ime = false;
|
||||
}
|
||||
|
||||
pub(crate) fn from_save_state(
|
||||
state: CpuSaveState<ColourFormat, R>,
|
||||
data: Vec<u8>,
|
||||
window: R,
|
||||
output: AudioOutput,
|
||||
serial_target: SerialTarget,
|
||||
camera: CameraWrapperRef<C>,
|
||||
) -> Self {
|
||||
Self {
|
||||
memory: Memory::from_save_state(
|
||||
state.memory,
|
||||
data,
|
||||
window,
|
||||
output,
|
||||
serial_target,
|
||||
camera,
|
||||
),
|
||||
reg: state.reg,
|
||||
last_instruction: state.last_instruction,
|
||||
last_instruction_addr: state.last_instruction_addr,
|
||||
halted: state.halted,
|
||||
should_halt_bug: state.should_halt_bug,
|
||||
cycle_count: state.cycle_count,
|
||||
is_skipping: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
|
Loading…
Add table
Reference in a new issue