save state restore
This commit is contained in:
parent
250cc92536
commit
5aa308f695
|
@ -1,7 +1,7 @@
|
||||||
use async_ringbuf::AsyncHeapConsumer;
|
use async_ringbuf::AsyncHeapConsumer;
|
||||||
use futures::executor;
|
use futures::executor;
|
||||||
use gb_emu_lib::{
|
use gb_emu_lib::{
|
||||||
connect::{AudioOutput, DownsampleType, EmulatorMessage, JoypadButtons, RomFile},
|
connect::{AudioOutput, CpuSaveState, DownsampleType, EmulatorMessage, JoypadButtons, RomFile},
|
||||||
EmulatorCore,
|
EmulatorCore,
|
||||||
};
|
};
|
||||||
use nih_plug::prelude::*;
|
use nih_plug::prelude::*;
|
||||||
|
@ -27,6 +27,7 @@ pub struct GameboyEmu {
|
||||||
vars: Option<EmuVars>,
|
vars: Option<EmuVars>,
|
||||||
frame_receiver: Arc<FrameReceiver>,
|
frame_receiver: Arc<FrameReceiver>,
|
||||||
key_handler: Arc<JoypadSender>,
|
key_handler: Arc<JoypadSender>,
|
||||||
|
last_save_state: Option<CpuSaveState<[u8; 4]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type FrameReceiver = Mutex<Option<Receiver<Vec<[u8; 4]>>>>;
|
type FrameReceiver = Mutex<Option<Receiver<Vec<[u8; 4]>>>>;
|
||||||
|
@ -36,6 +37,9 @@ const FRAMES_TO_BUFFER: usize = 1;
|
||||||
const INCLUDE_BOOTROM: bool = false;
|
const INCLUDE_BOOTROM: bool = false;
|
||||||
const DOWNSAMPLE_TYPE: DownsampleType = DownsampleType::ZeroOrderHold;
|
const DOWNSAMPLE_TYPE: DownsampleType = DownsampleType::ZeroOrderHold;
|
||||||
|
|
||||||
|
const ROM: &[u8; 65536] = include_bytes!("../../test-roms/mGB1_3_0.gb");
|
||||||
|
const BOOTROM: &[u8; 256] = include_bytes!("../../bootrom/dmg_boot.bin");
|
||||||
|
|
||||||
impl Plugin for GameboyEmu {
|
impl Plugin for GameboyEmu {
|
||||||
const NAME: &'static str = "Gameboy";
|
const NAME: &'static str = "Gameboy";
|
||||||
|
|
||||||
|
@ -48,7 +52,7 @@ impl Plugin for GameboyEmu {
|
||||||
const VERSION: &'static str = "0.1";
|
const VERSION: &'static str = "0.1";
|
||||||
|
|
||||||
const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[AudioIOLayout {
|
const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[AudioIOLayout {
|
||||||
main_input_channels: NonZeroU32::new(2),
|
main_input_channels: None,
|
||||||
main_output_channels: NonZeroU32::new(2),
|
main_output_channels: NonZeroU32::new(2),
|
||||||
|
|
||||||
aux_input_ports: &[],
|
aux_input_ports: &[],
|
||||||
|
@ -60,6 +64,9 @@ impl Plugin for GameboyEmu {
|
||||||
names: PortNames::const_default(),
|
names: PortNames::const_default(),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
const MIDI_INPUT: MidiConfig = MidiConfig::MidiCCs;
|
||||||
|
const SAMPLE_ACCURATE_AUTOMATION: bool = true;
|
||||||
|
|
||||||
type SysExMessage = ();
|
type SysExMessage = ();
|
||||||
|
|
||||||
type BackgroundTask = ();
|
type BackgroundTask = ();
|
||||||
|
@ -118,25 +125,12 @@ impl Plugin for GameboyEmu {
|
||||||
vars.rx = rx;
|
vars.rx = rx;
|
||||||
} else {
|
} else {
|
||||||
let bootrom = if INCLUDE_BOOTROM {
|
let bootrom = if INCLUDE_BOOTROM {
|
||||||
Some(RomFile::Raw(
|
Some(RomFile::Raw(BOOTROM.to_vec()))
|
||||||
include_bytes!("../../bootrom/dmg_boot.bin").to_vec(),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = gb_emu_lib::Options {
|
let rom = RomFile::Raw(ROM.to_vec());
|
||||||
rom: RomFile::Raw(
|
|
||||||
include_bytes!("../../test-roms/Tetris.gb")
|
|
||||||
.to_vec()
|
|
||||||
.to_vec(),
|
|
||||||
),
|
|
||||||
save_path: None,
|
|
||||||
no_save: true,
|
|
||||||
bootrom,
|
|
||||||
connect_serial: false,
|
|
||||||
verbose: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (sender, receiver) = channel::<EmulatorMessage>();
|
let (sender, receiver) = channel::<EmulatorMessage>();
|
||||||
|
|
||||||
|
@ -152,8 +146,22 @@ impl Plugin for GameboyEmu {
|
||||||
*self.frame_receiver.lock().unwrap() = Some(frame_receiver);
|
*self.frame_receiver.lock().unwrap() = Some(frame_receiver);
|
||||||
*self.key_handler.lock().unwrap() = Some(key_handler);
|
*self.key_handler.lock().unwrap() = Some(key_handler);
|
||||||
|
|
||||||
let mut emulator_core =
|
let window = Box::new(renderer);
|
||||||
EmulatorCore::init(receiver, options, Box::new(renderer), output, None);
|
|
||||||
|
let mut emulator_core = if let Some(state) = self.last_save_state.take() {
|
||||||
|
EmulatorCore::from_save_state(state, rom, receiver, window, output)
|
||||||
|
} else {
|
||||||
|
let options = gb_emu_lib::Options {
|
||||||
|
rom,
|
||||||
|
save_path: None,
|
||||||
|
no_save: true,
|
||||||
|
bootrom,
|
||||||
|
connect_serial: false,
|
||||||
|
verbose: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
EmulatorCore::init(receiver, options, window, output, None)
|
||||||
|
};
|
||||||
emulator_core.run_until_buffer_full();
|
emulator_core.run_until_buffer_full();
|
||||||
|
|
||||||
self.vars = Some(EmuVars {
|
self.vars = Some(EmuVars {
|
||||||
|
@ -169,6 +177,7 @@ impl Plugin for GameboyEmu {
|
||||||
fn deactivate(&mut self) {
|
fn deactivate(&mut self) {
|
||||||
nih_log!("deactivating");
|
nih_log!("deactivating");
|
||||||
if let Some(ref mut vars) = self.vars {
|
if let Some(ref mut vars) = self.vars {
|
||||||
|
self.last_save_state = Some(vars.emulator_core.get_save_state());
|
||||||
match vars.sender.send(EmulatorMessage::Stop) {
|
match vars.sender.send(EmulatorMessage::Stop) {
|
||||||
Ok(_) => self.vars = None,
|
Ok(_) => self.vars = None,
|
||||||
Err(e) => nih_log!("error {e} sending message to emulator"),
|
Err(e) => nih_log!("error {e} sending message to emulator"),
|
||||||
|
@ -181,7 +190,7 @@ impl Vst3Plugin for GameboyEmu {
|
||||||
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";
|
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";
|
||||||
|
|
||||||
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] =
|
||||||
&[Vst3SubCategory::Distortion, Vst3SubCategory::Dynamics];
|
&[Vst3SubCategory::Instrument, Vst3SubCategory::Synth];
|
||||||
}
|
}
|
||||||
|
|
||||||
nih_export_vst3!(GameboyEmu);
|
nih_export_vst3!(GameboyEmu);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::processor::memory::mmio::gpu::Colour;
|
use crate::processor::memory::mmio::gpu::Colour;
|
||||||
pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState};
|
pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState};
|
||||||
|
pub use crate::processor::CpuSaveState;
|
||||||
pub use crate::{HEIGHT, WIDTH};
|
pub use crate::{HEIGHT, WIDTH};
|
||||||
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue