refactor options

This commit is contained in:
Alex Janka 2023-03-17 13:58:47 +11:00
parent 30a94868d1
commit 8edf466271
4 changed files with 114 additions and 95 deletions

View file

@ -10,7 +10,8 @@ use cpal::{
use futures::executor; use futures::executor;
use gb_emu_lib::{ use gb_emu_lib::{
connect::{ connect::{
AudioOutput, DownsampleType, EmulatorMessage, JoypadState, Renderer, RomFile, SerialTarget, AudioOutput, DownsampleType, EmulatorMessage, EmulatorOptions, JoypadState, Renderer,
RomFile, SerialTarget,
}, },
util::scale_buffer, util::scale_buffer,
EmulatorCore, EmulatorCore,
@ -77,17 +78,6 @@ fn main() {
3 3
}; };
let options = gb_emu_lib::Options::new(RomFile::Path(args.rom))
.with_save_path(args.save)
.with_serial_target(if args.connect_serial {
SerialTarget::Stdout
} else {
SerialTarget::None
})
.with_bootrom(args.bootrom.map(RomFile::Path))
.with_no_save(args.no_save)
.with_verbose(args.verbose);
let tile_window: Option<WindowRenderer> = if args.tile_window { let tile_window: Option<WindowRenderer> = if args.tile_window {
Some(WindowRenderer::new(factor, None)) Some(WindowRenderer::new(factor, None))
} else { } else {
@ -100,13 +90,23 @@ fn main() {
let (output, _stream) = create_audio_output(); let (output, _stream) = create_audio_output();
let mut core = EmulatorCore::init( let options = EmulatorOptions::new(
receiver,
options,
WindowRenderer::new(factor, Some(Gilrs::new().unwrap())), WindowRenderer::new(factor, Some(Gilrs::new().unwrap())),
RomFile::Path(args.rom),
output, output,
tile_window, )
); .with_save_path(args.save)
.with_serial_target(if args.connect_serial {
SerialTarget::Stdout
} else {
SerialTarget::None
})
.with_bootrom(args.bootrom.map(RomFile::Path))
.with_no_save(args.no_save)
.with_verbose(args.verbose)
.with_tile_window(tile_window);
let mut core = EmulatorCore::init(receiver, options);
match args.step_by { match args.step_by {
Some(step_size) => loop { Some(step_size) => loop {

View file

@ -1,7 +1,10 @@
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, SerialTarget}, connect::{
AudioOutput, DownsampleType, EmulatorMessage, EmulatorOptions, JoypadButtons, RomFile,
SerialTarget,
},
EmulatorCore, EmulatorCore,
}; };
use nih_plug::midi::MidiResult::Basic; use nih_plug::midi::MidiResult::Basic;
@ -253,21 +256,21 @@ impl Plugin for GameboyEmu {
{ {
EmulatorCore::from_save_state(state, rom, receiver, window, output, serial_target) EmulatorCore::from_save_state(state, rom, receiver, window, output, serial_target)
} else { } else {
let options = gb_emu_lib::Options::new(rom) let options = gb_emu_lib::Options::new(window, rom, output)
.with_bootrom(bootrom) .with_bootrom(bootrom)
.with_serial_target(serial_target) .with_serial_target(serial_target)
.force_no_save(); .force_no_save();
EmulatorCore::init(receiver, options, window, output, None) EmulatorCore::init(receiver, options)
}; };
#[cfg(not(feature = "savestate"))] #[cfg(not(feature = "savestate"))]
let mut emulator_core = { let mut emulator_core = {
let options = gb_emu_lib::Options::new(rom) let options = EmulatorOptions::new(window, rom, output)
.with_bootrom(bootrom) .with_bootrom(bootrom)
.with_serial_target(serial_target) .with_serial_target(serial_target)
.force_no_save(); .force_no_save();
EmulatorCore::init(receiver, options, window, output, None) EmulatorCore::init(receiver, options)
}; };
emulator_core.run_until_buffer_full(); emulator_core.run_until_buffer_full();

View file

@ -1,3 +1,5 @@
use std::marker::PhantomData;
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::memory::mmio::serial::SerialTarget; pub use crate::processor::memory::mmio::serial::SerialTarget;
@ -62,3 +64,81 @@ impl AudioOutput {
) )
} }
} }
#[non_exhaustive]
pub struct EmulatorOptions<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>> {
pub(crate) window: R,
pub(crate) tile_window: Option<R>,
pub(crate) rom: RomFile,
pub(crate) output: AudioOutput,
pub(crate) save_path: Option<String>,
pub(crate) no_save: bool,
pub(crate) bootrom: Option<RomFile>,
pub(crate) serial_target: SerialTarget,
pub(crate) verbose: bool,
pub(crate) spooky: PhantomData<ColourFormat>,
}
impl<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>>
EmulatorOptions<ColourFormat, R>
{
pub fn new(window: R, rom: RomFile, output: AudioOutput) -> Self {
Self {
window,
tile_window: None,
rom,
output,
save_path: None,
no_save: false,
bootrom: None,
serial_target: SerialTarget::None,
verbose: false,
spooky: PhantomData,
}
}
pub fn with_save_path(mut self, path: Option<String>) -> Self {
self.save_path = path;
self
}
pub fn force_no_save(mut self) -> Self {
self.no_save = true;
self
}
pub fn with_no_save(mut self, no_save: bool) -> Self {
self.no_save = no_save;
self
}
pub fn with_verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
pub fn with_bootrom(mut self, bootrom: Option<RomFile>) -> Self {
self.bootrom = bootrom;
self
}
pub fn with_stdout(mut self) -> Self {
self.serial_target = SerialTarget::Stdout;
self
}
pub fn with_serial_target(mut self, target: SerialTarget) -> Self {
self.serial_target = target;
self
}
pub fn with_tile_window(mut self, window: Option<R>) -> Self {
self.tile_window = window;
self
}
pub fn verbose(mut self) -> Self {
self.verbose = true;
self
}
}

View file

@ -1,7 +1,7 @@
#![feature(exclusive_range_pattern, let_chains, bigint_helper_methods)] #![feature(exclusive_range_pattern, let_chains, bigint_helper_methods)]
use crate::{processor::memory::Memory, util::pause}; use crate::{processor::memory::Memory, util::pause};
use connect::{AudioOutput, EmulatorMessage, Renderer, RomFile, SerialTarget}; use connect::{AudioOutput, EmulatorMessage, EmulatorOptions, Renderer, RomFile, SerialTarget};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use processor::{ use processor::{
memory::{mmio::gpu::Colour, Rom}, memory::{mmio::gpu::Colour, Rom},
@ -22,69 +22,6 @@ mod constants;
mod processor; mod processor;
pub mod util; pub mod util;
#[non_exhaustive]
pub struct Options {
pub rom: RomFile,
pub save_path: Option<String>,
pub no_save: bool,
pub bootrom: Option<RomFile>,
pub serial_target: SerialTarget,
pub verbose: bool,
}
impl Options {
pub fn new(rom: RomFile) -> Self {
Self {
rom,
save_path: None,
no_save: false,
bootrom: None,
serial_target: SerialTarget::None,
verbose: false,
}
}
pub fn with_save_path(mut self, path: Option<String>) -> Self {
self.save_path = path;
self
}
pub fn force_no_save(mut self) -> Self {
self.no_save = true;
self
}
pub fn with_no_save(mut self, no_save: bool) -> Self {
self.no_save = no_save;
self
}
pub fn with_verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
pub fn with_bootrom(mut self, bootrom: Option<RomFile>) -> Self {
self.bootrom = bootrom;
self
}
pub fn with_stdout(mut self) -> Self {
self.serial_target = SerialTarget::Stdout;
self
}
pub fn with_serial_target(mut self, target: SerialTarget) -> Self {
self.serial_target = target;
self
}
pub fn 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;
@ -101,10 +38,7 @@ pub struct EmulatorCore<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFo
impl<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>> EmulatorCore<ColourFormat, R> { impl<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>> EmulatorCore<ColourFormat, R> {
pub fn init( pub fn init(
receiver: Receiver<EmulatorMessage>, receiver: Receiver<EmulatorMessage>,
options: Options, mut options: EmulatorOptions<ColourFormat, R>,
mut window: R,
output: AudioOutput,
tile_window: Option<R>,
) -> Self { ) -> Self {
if options.verbose { if options.verbose {
VERBOSE.set(true).unwrap(); VERBOSE.set(true).unwrap();
@ -133,8 +67,10 @@ impl<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>> EmulatorCore
RomFile::Raw(data) => Rom::load(data, None), RomFile::Raw(data) => Rom::load(data, None),
}; };
window.prepare(WIDTH, HEIGHT); options.window.prepare(WIDTH, HEIGHT);
window.set_title(format!("{} on {}", rom.get_title(), rom.mbc_type())); options
.window
.set_title(format!("{} on {}", rom.get_title(), rom.mbc_type()));
let bootrom_enabled = options.bootrom.is_some(); let bootrom_enabled = options.bootrom.is_some();
let bootrom: Option<Vec<u8>> = options.bootrom.map(|v| match v { let bootrom: Option<Vec<u8>> = options.bootrom.map(|v| match v {
@ -154,10 +90,10 @@ impl<ColourFormat: From<Colour> + Clone, R: Renderer<ColourFormat>> EmulatorCore
Memory::init( Memory::init(
bootrom, bootrom,
rom, rom,
window, options.window,
output, options.output,
options.serial_target, options.serial_target,
tile_window, options.tile_window,
), ),
bootrom_enabled, bootrom_enabled,
), ),