diff --git a/gb-emu/src/main.rs b/gb-emu/src/main.rs index 775dbad..0bea01a 100644 --- a/gb-emu/src/main.rs +++ b/gb-emu/src/main.rs @@ -88,8 +88,8 @@ fn main() { .with_no_save(args.no_save) .with_verbose(args.verbose); - let tile_window: Option>> = if args.tile_window { - Some(Box::new(WindowRenderer::new(factor, None))) + let tile_window: Option = if args.tile_window { + Some(WindowRenderer::new(factor, None)) } else { None }; @@ -103,7 +103,7 @@ fn main() { let mut core = EmulatorCore::init( receiver, options, - Box::new(WindowRenderer::new(factor, Some(Gilrs::new().unwrap()))), + WindowRenderer::new(factor, Some(Gilrs::new().unwrap())), output, tile_window, ); diff --git a/gb-vst/Cargo.toml b/gb-vst/Cargo.toml index be67d00..d4f1070 100644 --- a/gb-vst/Cargo.toml +++ b/gb-vst/Cargo.toml @@ -12,7 +12,7 @@ default = [] savestate = [] [dependencies] -gb-emu-lib = { path = "../lib", features = ["async"] } +gb-emu-lib = { path = "../lib" } nih_plug = { path = "../vendored/nih-plug", features = ["standalone"] } baseview = { path = "../vendored/baseview" } pixels = "0.11" diff --git a/gb-vst/src/lib.rs b/gb-vst/src/lib.rs index a56286d..541a146 100644 --- a/gb-vst/src/lib.rs +++ b/gb-vst/src/lib.rs @@ -49,7 +49,7 @@ struct EmuParams { struct EmuVars { rx: AsyncHeapConsumer<[f32; 2]>, sender: Sender, - emulator_core: EmulatorCore<[u8; 4]>, + emulator_core: EmulatorCore<[u8; 4], EmulatorRenderer>, serial_tx: Sender, } @@ -236,13 +236,11 @@ impl Plugin for GameboyEmu { DOWNSAMPLE_TYPE, ); - let (renderer, frame_receiver, key_handler) = EmulatorRenderer::new(); + let (window, frame_receiver, key_handler) = EmulatorRenderer::new(); *self.frame_receiver.lock().unwrap() = Some(frame_receiver); *self.key_handler.lock().unwrap() = Some(key_handler); - let window = Box::new(renderer); - let (serial_tx, gb_serial_rx) = mpsc::channel::(); let serial_target = SerialTarget::Custom { rx: Some(gb_serial_rx), diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 04f8761..e5c7cbc 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [features] default = [] -async = [] clocked-serial = [] [dependencies] diff --git a/lib/src/connect/mod.rs b/lib/src/connect/mod.rs index 12a73a3..c6c5433 100644 --- a/lib/src/connect/mod.rs +++ b/lib/src/connect/mod.rs @@ -20,20 +20,6 @@ pub enum RomFile { Raw(Vec), } -#[cfg(feature = "async")] -pub trait Renderer>: Send { - 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) {} -} - -#[cfg(not(feature = "async"))] pub trait Renderer> { fn prepare(&mut self, width: usize, height: usize); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 3fbb192..4028ca6 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -93,18 +93,18 @@ static VERBOSE: OnceCell = OnceCell::new(); pub const WIDTH: usize = 160; pub const HEIGHT: usize = 144; -pub struct EmulatorCore + Clone> { +pub struct EmulatorCore + Clone, R: Renderer> { receiver: Receiver, - cpu: Cpu, + cpu: Cpu, } -impl + Clone> EmulatorCore { +impl + Clone, R: Renderer> EmulatorCore { pub fn init( receiver: Receiver, options: Options, - mut window: Box>, + mut window: R, output: AudioOutput, - tile_window: Option>>, + tile_window: Option, ) -> Self { if options.verbose { VERBOSE.set(true).unwrap(); @@ -164,7 +164,7 @@ impl + Clone> EmulatorCore { ) } - fn new(receiver: Receiver, cpu: Cpu) -> Self { + fn new(receiver: Receiver, cpu: Cpu) -> Self { Self { receiver, cpu } } @@ -217,15 +217,15 @@ impl + Clone> EmulatorCore { } } - pub fn get_save_state(&self) -> CpuSaveState { + pub fn get_save_state(&self) -> CpuSaveState { CpuSaveState::create(&self.cpu) } pub fn from_save_state( - state: CpuSaveState, + state: CpuSaveState, rom: RomFile, receiver: Receiver, - window: Box>, + window: R, output: AudioOutput, serial_target: SerialTarget, ) -> Self { diff --git a/lib/src/processor/instructions/instructions.rs b/lib/src/processor/instructions/instructions.rs index facb28d..98d7d2d 100644 --- a/lib/src/processor/instructions/instructions.rs +++ b/lib/src/processor/instructions/instructions.rs @@ -1,9 +1,10 @@ use crate::{ + connect::Renderer, processor::{memory::mmio::gpu::Colour, Cpu, Direction, Flags, Reg8, SplitRegister}, util::{clear_bit, get_bit, set_bit}, }; -impl + Clone> Cpu { +impl + Clone, R: Renderer> Cpu { pub(crate) fn and(&mut self, first: u8, second: u8) -> u8 { let result = first & second; self.set_or_clear_flag(Flags::Zero, result == 0x0); diff --git a/lib/src/processor/instructions/primitives.rs b/lib/src/processor/instructions/primitives.rs index 8ebced6..462e0d9 100644 --- a/lib/src/processor/instructions/primitives.rs +++ b/lib/src/processor/instructions/primitives.rs @@ -1,10 +1,11 @@ use crate::{ + connect::Renderer, processor::{memory::mmio::gpu::Colour, Cpu, Direction, Flags, SplitRegister}, util::{as_signed, get_bit, get_rotation_carry, rotate, Nibbles}, }; use std::ops::{BitAnd, BitOr}; -impl + Clone> Cpu { +impl + Clone, R: Renderer> Cpu { pub(crate) fn pop_word(&mut self) -> u16 { let mut word: u16 = 0x0; word.set_low(self.memory.get(self.reg.sp)); diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index b9e1a8b..3f2a446 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -22,7 +22,7 @@ pub(crate) mod rom; pub(crate) type Address = u16; -pub struct Memory + Clone> { +pub struct Memory + Clone, R: Renderer> { bootrom: Option>, rom: Rom, ram: [u8; 8192], @@ -32,7 +32,7 @@ pub struct Memory + Clone> { pub(super) ime_scheduled: u8, dma_addr: u8, joypad: Joypad, - gpu: Gpu, + gpu: Gpu, apu: Apu, serial: Serial, timers: Timer, @@ -40,7 +40,7 @@ pub struct Memory + Clone> { #[serde_with::serde_as] #[derive(Serialize, Deserialize)] -pub struct MemorySaveState + Clone> { +pub struct MemorySaveState + Clone, R: Renderer> { rom: RomSaveState, #[serde_as(as = "[_; 8192]")] ram: [u8; 8192], @@ -51,14 +51,16 @@ pub struct MemorySaveState + Clone> { pub(super) ime_scheduled: u8, dma_addr: u8, joypad: Joypad, - gpu: GpuSaveState, + gpu: GpuSaveState, apu: ApuSaveState, serial: SerialSaveState, timers: Timer, } -impl + Clone> MemorySaveState { - pub fn create(memory: &Memory) -> Self { +impl + Clone, R: Renderer> + MemorySaveState +{ + pub fn create(memory: &Memory) -> Self { Self { rom: RomSaveState::create(&memory.rom), ram: memory.ram, @@ -76,14 +78,14 @@ impl + Clone> MemorySaveState { } } -impl + Clone> Memory { +impl + Clone, R: Renderer> Memory { pub fn init( bootrom: Option>, rom: Rom, - window: Box>, + window: R, output: AudioOutput, serial_target: SerialTarget, - tile_window: Option>>, + tile_window: Option, ) -> Self { Self { bootrom, @@ -274,9 +276,9 @@ impl + Clone> Memory { } pub fn from_save_state( - state: MemorySaveState, + state: MemorySaveState, data: Vec, - window: Box>, + window: R, output: AudioOutput, serial_target: SerialTarget, ) -> Self { @@ -298,7 +300,7 @@ impl + Clone> Memory { } } -impl + Clone> Cpu { +impl + Clone, R: Renderer> Cpu { pub fn increment_timers(&mut self, machine_cycles: u8) { let steps = (machine_cycles as usize) * 4; diff --git a/lib/src/processor/memory/mmio/gpu.rs b/lib/src/processor/memory/mmio/gpu.rs index 13d3359..37e1a8c 100644 --- a/lib/src/processor/memory/mmio/gpu.rs +++ b/lib/src/processor/memory/mmio/gpu.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use self::{ tile_window::TileWindow, types::{ @@ -21,18 +23,18 @@ mod types; const TILE_WINDOW_WIDTH: usize = 16 * 8; const TILE_WINDOW_HEIGHT: usize = 24 * 8; -pub struct Gpu> { +pub struct Gpu, R: Renderer> { pub buffer: Vec, pub vram: Vram, pub oam: Oam, - pub window: Box>, + pub window: R, is_bg_zero: Vec, lcdc: Lcdc, stat: Stat, mode_clock: usize, scanline: u8, lyc: u8, - tile_window: Option>, + tile_window: Option>, window_lc: u8, has_window_been_enabled: bool, bg_palette: Palette, @@ -46,7 +48,7 @@ pub struct Gpu> { } #[derive(Serialize, Deserialize)] -pub struct GpuSaveState> { +pub struct GpuSaveState, R: Renderer> { buffer: Vec, vram: Vram, oam: Oam, @@ -66,10 +68,12 @@ pub struct GpuSaveState> { wx: u8, wy: u8, prev_stat: bool, + #[serde(skip)] + spooky: PhantomData, } -impl + Clone> GpuSaveState { - pub fn create(gpu: &Gpu) -> Self { +impl + Clone, R: Renderer> GpuSaveState { + pub fn create(gpu: &Gpu) -> Self { Self { buffer: gpu.buffer.clone(), vram: gpu.vram, @@ -90,15 +94,13 @@ impl + Clone> GpuSaveState { wx: gpu.wx, wy: gpu.wy, prev_stat: gpu.prev_stat, + spooky: PhantomData, } } } -impl + Clone> Gpu { - pub fn new( - window: Box>, - tile_window_renderer: Option>>, - ) -> Self { +impl + Clone, R: Renderer> Gpu { + pub fn new(window: R, tile_window_renderer: Option) -> Self { let tile_window = if let Some(mut tile_window_renderer) = tile_window_renderer { tile_window_renderer.prepare(TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT); Some(TileWindow::new(tile_window_renderer)) @@ -133,9 +135,9 @@ impl + Clone> Gpu { } pub fn from_save_state( - state: GpuSaveState, - window: Box>, - tile_window_renderer: Option>>, + state: GpuSaveState, + window: R, + tile_window_renderer: Option, ) -> Self { let tile_window = if let Some(mut tile_window_renderer) = tile_window_renderer { tile_window_renderer.prepare(TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT); diff --git a/lib/src/processor/memory/mmio/gpu/addresses.rs b/lib/src/processor/memory/mmio/gpu/addresses.rs index a5b3bf2..d38e730 100644 --- a/lib/src/processor/memory/mmio/gpu/addresses.rs +++ b/lib/src/processor/memory/mmio/gpu/addresses.rs @@ -1,11 +1,14 @@ -use crate::util::{get_bit, set_or_clear_bit}; +use crate::{ + connect::Renderer, + util::{get_bit, set_or_clear_bit}, +}; use super::{ types::{DrawMode, ObjSize, Palette, TiledataArea, TilemapArea}, Colour, Gpu, }; -impl> Gpu { +impl, R: Renderer> Gpu { pub fn update_lcdc(&mut self, data: u8) { self.lcdc.enable = get_bit(data, 7); self.lcdc.window_tilemap = if get_bit(data, 6) { diff --git a/lib/src/processor/memory/mmio/gpu/tile_window.rs b/lib/src/processor/memory/mmio/gpu/tile_window.rs index 01e95cc..1c6bed0 100644 --- a/lib/src/processor/memory/mmio/gpu/tile_window.rs +++ b/lib/src/processor/memory/mmio/gpu/tile_window.rs @@ -6,13 +6,13 @@ use crate::{ use super::{types::Vram, Colour}; -pub(super) struct TileWindow> { +pub(super) struct TileWindow, R: Renderer> { sprite_buffer: Vec, - sprite_renderer: Box>, + sprite_renderer: R, } -impl> TileWindow { - pub(super) fn new(window: Box>) -> Self { +impl, R: Renderer> TileWindow { + pub(super) fn new(window: R) -> Self { let mut sprite_buffer = Vec::new(); sprite_buffer.reserve_exact(TILE_WINDOW_WIDTH * TILE_WINDOW_HEIGHT); diff --git a/lib/src/processor/mod.rs b/lib/src/processor/mod.rs index af8aca0..3ccc859 100644 --- a/lib/src/processor/mod.rs +++ b/lib/src/processor/mod.rs @@ -23,8 +23,8 @@ pub(crate) enum Direction { Right, } -pub struct Cpu + Clone> { - pub memory: Memory, +pub struct Cpu + Clone, R: Renderer> { + pub memory: Memory, pub reg: Registers, pub last_instruction: u8, last_instruction_addr: u16, @@ -33,8 +33,8 @@ pub struct Cpu + Clone> { } #[derive(Serialize, Deserialize)] -pub struct CpuSaveState + Clone> { - memory: MemorySaveState, +pub struct CpuSaveState + Clone, R: Renderer> { + memory: MemorySaveState, reg: Registers, last_instruction: u8, last_instruction_addr: u16, @@ -42,8 +42,8 @@ pub struct CpuSaveState + Clone> { should_halt_bug: bool, } -impl + Clone> CpuSaveState { - pub fn create(cpu: &Cpu) -> Self { +impl + Clone, R: Renderer> CpuSaveState { + pub fn create(cpu: &Cpu) -> Self { Self { memory: MemorySaveState::create(&cpu.memory), reg: cpu.reg, @@ -55,8 +55,8 @@ impl + Clone> CpuSaveState { } } -impl + Clone> Cpu { - pub fn new(mut memory: Memory, run_bootrom: bool) -> Self { +impl + Clone, R: Renderer> Cpu { + pub fn new(mut memory: Memory, run_bootrom: bool) -> Self { if !run_bootrom { memory.cpu_ram_init(); } @@ -155,9 +155,9 @@ impl + Clone> Cpu { } pub fn from_save_state( - state: CpuSaveState, + state: CpuSaveState, data: Vec, - window: Box>, + window: R, output: AudioOutput, serial_target: SerialTarget, ) -> Self { diff --git a/lib/src/processor/opcodes.rs b/lib/src/processor/opcodes.rs index e858e88..d2e7012 100644 --- a/lib/src/processor/opcodes.rs +++ b/lib/src/processor/opcodes.rs @@ -1,4 +1,5 @@ use crate::{ + connect::Renderer, processor::{ instructions::instructions::{res, set}, Cpu, Flags, Reg8, SplitRegister, @@ -8,7 +9,7 @@ use crate::{ use super::memory::mmio::gpu::Colour; -impl + Clone> Cpu { +impl + Clone, R: Renderer> Cpu { pub fn run_opcode(&mut self, opcode: u8) -> u8 { match opcode { 0x00 => {