use std::marker::PhantomData; 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}; pub enum EmulatorMessage { Stop, } #[derive(Clone, Copy)] pub enum DownsampleType { Linear, ZeroOrderHold, } pub enum RomFile { Path(String), Raw(Vec), } pub trait Renderer> { fn prepare(&mut self, width: usize, height: usize); fn display(&mut self, buffer: &[Format]); fn set_title(&mut self, _title: String) {} fn latest_joypad_state(&mut self) -> JoypadState; fn set_rumble(&mut self, _rumbling: bool) {} } pub struct AudioOutput { pub sample_rate: f32, pub send_rb: AsyncHeapProducer<[f32; 2]>, pub wait_for_output: bool, pub downsample_type: DownsampleType, } impl AudioOutput { pub fn new( sample_rate: f32, wait_for_output: bool, frames_to_buffer: usize, downsample_type: DownsampleType, ) -> (Self, AsyncHeapConsumer<[f32; 2]>) { let rb_len = (sample_rate as usize / 60) * frames_to_buffer; let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len); let (send_rb, rx) = rb.split(); ( Self { sample_rate, send_rb, wait_for_output, downsample_type, }, rx, ) } } pub trait PocketCamera { // resolution - 128x128 fn capture_greyscale(&mut self) -> [u8; 128 * 128]; } #[non_exhaustive] pub struct EmulatorOptions where ColourFormat: From + Clone, R: Renderer, { pub(crate) window: R, pub(crate) tile_window: Option, pub(crate) rom: RomFile, pub(crate) output: AudioOutput, pub(crate) save_path: Option, pub(crate) no_save: bool, pub(crate) bootrom: Option, pub(crate) serial_target: SerialTarget, pub(crate) verbose: bool, pub(crate) spooky: PhantomData, } impl EmulatorOptions where ColourFormat: From + Clone, R: Renderer, { 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) -> 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) -> 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) -> Self { self.tile_window = window; self } pub fn verbose(mut self) -> Self { self.verbose = true; self } }