should restore from save state... doesn't, but should
This commit is contained in:
parent
5aa308f695
commit
b5fa2e6690
|
@ -5,6 +5,7 @@ use gb_emu_lib::{
|
||||||
EmulatorCore,
|
EmulatorCore,
|
||||||
};
|
};
|
||||||
use nih_plug::prelude::*;
|
use nih_plug::prelude::*;
|
||||||
|
use nih_plug::{midi::MidiResult::Basic, params::persist::PersistentField};
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
mpsc::{channel, Receiver, Sender},
|
mpsc::{channel, Receiver, Sender},
|
||||||
Arc, Mutex,
|
Arc, Mutex,
|
||||||
|
@ -13,8 +14,29 @@ use ui::{Emulator, EmulatorRenderer};
|
||||||
|
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct SaveStateParam {
|
||||||
|
state: Arc<Mutex<Option<CpuSaveState<[u8; 4]>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Params, Default)]
|
#[derive(Params, Default)]
|
||||||
struct EmuParams {}
|
struct EmuParams {
|
||||||
|
#[persist = "save_state"]
|
||||||
|
last_save_state: SaveStateParam,
|
||||||
|
}
|
||||||
|
|
||||||
struct EmuVars {
|
struct EmuVars {
|
||||||
rx: AsyncHeapConsumer<[f32; 2]>,
|
rx: AsyncHeapConsumer<[f32; 2]>,
|
||||||
|
@ -27,7 +49,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]>>,
|
params: Arc<EmuParams>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type FrameReceiver = Mutex<Option<Receiver<Vec<[u8; 4]>>>>;
|
type FrameReceiver = Mutex<Option<Receiver<Vec<[u8; 4]>>>>;
|
||||||
|
@ -72,15 +94,18 @@ impl Plugin for GameboyEmu {
|
||||||
type BackgroundTask = ();
|
type BackgroundTask = ();
|
||||||
|
|
||||||
fn params(&self) -> Arc<dyn Params> {
|
fn params(&self) -> Arc<dyn Params> {
|
||||||
Arc::new(EmuParams::default())
|
self.params.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &mut Buffer,
|
buffer: &mut Buffer,
|
||||||
_: &mut AuxiliaryBuffers,
|
_: &mut AuxiliaryBuffers,
|
||||||
_: &mut impl ProcessContext<Self>,
|
_c: &mut impl ProcessContext<Self>,
|
||||||
) -> ProcessStatus {
|
) -> ProcessStatus {
|
||||||
|
while let Some(event) = _c.next_event() {
|
||||||
|
if let Some(Basic(_midi)) = event.as_midi() {}
|
||||||
|
}
|
||||||
if let Some(ref mut vars) = self.vars {
|
if let Some(ref mut vars) = self.vars {
|
||||||
if buffer.channels() != 2 {
|
if buffer.channels() != 2 {
|
||||||
panic!()
|
panic!()
|
||||||
|
@ -97,6 +122,7 @@ impl Plugin for GameboyEmu {
|
||||||
}
|
}
|
||||||
vars.emulator_core.run_until_buffer_full();
|
vars.emulator_core.run_until_buffer_full();
|
||||||
}
|
}
|
||||||
|
self.update_save_state();
|
||||||
ProcessStatus::KeepAlive
|
ProcessStatus::KeepAlive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,20 +174,16 @@ impl Plugin for GameboyEmu {
|
||||||
|
|
||||||
let window = Box::new(renderer);
|
let window = Box::new(renderer);
|
||||||
|
|
||||||
let mut emulator_core = if let Some(state) = self.last_save_state.take() {
|
let mut emulator_core =
|
||||||
EmulatorCore::from_save_state(state, rom, receiver, window, output)
|
if let Some(state) = self.params.last_save_state.state.lock().unwrap().take() {
|
||||||
} else {
|
EmulatorCore::from_save_state(state, rom, receiver, window, output)
|
||||||
let options = gb_emu_lib::Options {
|
} else {
|
||||||
rom,
|
let options = gb_emu_lib::Options::new(rom)
|
||||||
save_path: None,
|
.with_bootrom(bootrom)
|
||||||
no_save: true,
|
.force_no_save();
|
||||||
bootrom,
|
|
||||||
connect_serial: false,
|
|
||||||
verbose: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
EmulatorCore::init(receiver, options, window, output, None)
|
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 +191,7 @@ impl Plugin for GameboyEmu {
|
||||||
sender,
|
sender,
|
||||||
emulator_core,
|
emulator_core,
|
||||||
});
|
});
|
||||||
|
self.update_save_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -176,8 +199,8 @@ impl Plugin for GameboyEmu {
|
||||||
|
|
||||||
fn deactivate(&mut self) {
|
fn deactivate(&mut self) {
|
||||||
nih_log!("deactivating");
|
nih_log!("deactivating");
|
||||||
|
self.update_save_state();
|
||||||
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"),
|
||||||
|
@ -186,6 +209,15 @@ impl Plugin for GameboyEmu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GameboyEmu {
|
||||||
|
fn update_save_state(&mut self) {
|
||||||
|
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 {
|
impl Vst3Plugin for GameboyEmu {
|
||||||
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";
|
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ mod constants;
|
||||||
mod processor;
|
mod processor;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub rom: RomFile,
|
pub rom: RomFile,
|
||||||
pub save_path: Option<String>,
|
pub save_path: Option<String>,
|
||||||
|
@ -31,6 +32,44 @@ pub struct Options {
|
||||||
pub verbose: bool,
|
pub verbose: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Options {
|
||||||
|
pub fn new(rom: RomFile) -> Self {
|
||||||
|
Self {
|
||||||
|
rom,
|
||||||
|
save_path: None,
|
||||||
|
no_save: false,
|
||||||
|
bootrom: None,
|
||||||
|
connect_serial: false,
|
||||||
|
verbose: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_save_path(mut self, path: String) -> Self {
|
||||||
|
self.save_path = Some(path);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn force_no_save(mut self) -> Self {
|
||||||
|
self.no_save = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_bootrom(mut self, bootrom: Option<RomFile>) -> Self {
|
||||||
|
self.bootrom = bootrom;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_serial(mut self) -> Self {
|
||||||
|
self.connect_serial = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_verbose(mut self) -> Self {
|
||||||
|
self.verbose = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mut PAUSE_ENABLED: bool = false;
|
static mut PAUSE_ENABLED: bool = false;
|
||||||
static mut PAUSE_QUEUED: bool = false;
|
static mut PAUSE_QUEUED: bool = false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue