From aaca3ff5b232266dee7b6e60a4d377e23f397708 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Wed, 8 Mar 2023 11:28:32 +1100 Subject: [PATCH] emu works again --- gb-emu/Cargo.toml | 2 +- gb-emu/src/main.rs | 6 ++--- gb-vst/Cargo.toml | 2 +- gb-vst/src/lib.rs | 2 +- lib/Cargo.toml | 4 +++ lib/src/connect/mod.rs | 27 +++++++++++++++++--- lib/src/processor/instructions/primitives.rs | 5 +++- lib/src/processor/memory/mmio/apu.rs | 6 ++++- 8 files changed, 42 insertions(+), 12 deletions(-) diff --git a/gb-emu/Cargo.toml b/gb-emu/Cargo.toml index 59886ba..c5e7bb2 100644 --- a/gb-emu/Cargo.toml +++ b/gb-emu/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gb-emu-lib = { path = "../lib" } +gb-emu-lib = { path = "../lib", features = [] } clap = {version = "4.1.8", features = ["derive"]} minifb = { path = "../vendored/rust_minifb" } gilrs = "0.10.1" diff --git a/gb-emu/src/main.rs b/gb-emu/src/main.rs index e610ca0..fa628a4 100644 --- a/gb-emu/src/main.rs +++ b/gb-emu/src/main.rs @@ -85,7 +85,7 @@ fn main() { cycle_count: args.cycle_count, }; - let tile_window: Option> = if args.tile_window { + let tile_window: Option>> = if args.tile_window { Some(Box::new(WindowRenderer::new(factor, None))) } else { None @@ -132,7 +132,7 @@ fn create_audio_output() -> (AudioOutput, Stream) { let sample_rate = config.sample_rate().0; - let (output, mut rx) = AudioOutput::new(sample_rate as f32); + let (output, mut rx) = AudioOutput::new_unfilled(sample_rate as f32, true); let stream = device .build_output_stream( @@ -183,7 +183,7 @@ impl WindowRenderer { } } -impl Renderer for WindowRenderer { +impl Renderer for WindowRenderer { fn prepare(&mut self, width: usize, height: usize) { self.width = width; self.height = height; diff --git a/gb-vst/Cargo.toml b/gb-vst/Cargo.toml index 4b1a9ca..2922ed7 100644 --- a/gb-vst/Cargo.toml +++ b/gb-vst/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gb-emu-lib = { path = "../lib" } +gb-emu-lib = { path = "../lib", features = ["async"] } nih_plug = { path = "../vendored/nih-plug", features = ["standalone"] } baseview = { path = "../vendored/baseview" } pixels = "0.11.0" diff --git a/gb-vst/src/lib.rs b/gb-vst/src/lib.rs index d1a6c5c..a09fb38 100644 --- a/gb-vst/src/lib.rs +++ b/gb-vst/src/lib.rs @@ -107,7 +107,7 @@ impl Plugin for GameboyEmu { }; let (sender, receiver) = channel::(); - let (output, rx) = AudioOutput::new_unfilled(buffer_config.sample_rate); + let (output, rx) = AudioOutput::new_unfilled(buffer_config.sample_rate, false); let (renderer, frame_receiver) = EmulatorRenderer::new(); diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 52c959f..3094c46 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = [] +async = [] + [dependencies] rand = "0.8.5" async-ringbuf = "0.1.2" diff --git a/lib/src/connect/mod.rs b/lib/src/connect/mod.rs index a5a99fd..cdb68af 100644 --- a/lib/src/connect/mod.rs +++ b/lib/src/connect/mod.rs @@ -13,6 +13,7 @@ pub enum RomFile { Raw(Vec), } +#[cfg(feature = "async")] pub trait Renderer>: Send { fn prepare(&mut self, width: usize, height: usize); @@ -25,26 +26,43 @@ pub trait Renderer>: Send { fn set_rumble(&mut self, _rumbling: bool) {} } +#[cfg(not(feature = "async"))] +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, } impl AudioOutput { - pub fn new(sample_rate: f32) -> (Self, AsyncHeapConsumer<[f32; 2]>) { - let (mut output, rx) = Self::new_unfilled(sample_rate); + pub fn new(sample_rate: f32, wait_for_output: bool) -> (Self, AsyncHeapConsumer<[f32; 2]>) { + let (mut output, rx) = Self::new_unfilled(sample_rate, wait_for_output); executor::block_on( output .send_rb - .push_iter(vec![[0.; 2]; output.send_rb.len() - 1].into_iter()), + .push_iter(vec![[0.; 2]; output.send_rb.free_len() - 1].into_iter()), ) .unwrap(); (output, rx) } - pub fn new_unfilled(sample_rate: f32) -> (Self, AsyncHeapConsumer<[f32; 2]>) { + pub fn new_unfilled( + sample_rate: f32, + wait_for_output: bool, + ) -> (Self, AsyncHeapConsumer<[f32; 2]>) { let rb_len = sample_rate as usize / (60 * 2); let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len); @@ -54,6 +72,7 @@ impl AudioOutput { Self { sample_rate, send_rb, + wait_for_output, }, rx, ) diff --git a/lib/src/processor/instructions/primitives.rs b/lib/src/processor/instructions/primitives.rs index 9853f26..8ebced6 100644 --- a/lib/src/processor/instructions/primitives.rs +++ b/lib/src/processor/instructions/primitives.rs @@ -145,7 +145,10 @@ impl + Clone> Cpu { self.set_or_clear_flag(Flags::Zero, result == 0x0); self.set_or_clear_flag( Flags::HalfCarry, - first.get_low_nibble() - (second.get_low_nibble() + if with_carry { 1 } else { 0 }) + first + .get_low_nibble() + .borrowing_sub(second.get_low_nibble(), with_carry) + .0 > 0xF, ); result diff --git a/lib/src/processor/memory/mmio/apu.rs b/lib/src/processor/memory/mmio/apu.rs index 83a8b86..12a4608 100644 --- a/lib/src/processor/memory/mmio/apu.rs +++ b/lib/src/processor/memory/mmio/apu.rs @@ -122,7 +122,11 @@ impl Apu { } fn push_audio(&mut self) { - let length = self.out_buffer.len().min(self.output.send_rb.free_len()); + let length = if self.output.wait_for_output { + self.out_buffer.len() + } else { + self.out_buffer.len().min(self.output.send_rb.free_len()) + }; executor::block_on( self.output