emu works again
This commit is contained in:
parent
4bae07f165
commit
aaca3ff5b2
|
@ -6,7 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gb-emu-lib = { path = "../lib" }
|
gb-emu-lib = { path = "../lib", features = [] }
|
||||||
clap = {version = "4.1.8", features = ["derive"]}
|
clap = {version = "4.1.8", features = ["derive"]}
|
||||||
minifb = { path = "../vendored/rust_minifb" }
|
minifb = { path = "../vendored/rust_minifb" }
|
||||||
gilrs = "0.10.1"
|
gilrs = "0.10.1"
|
||||||
|
|
|
@ -85,7 +85,7 @@ fn main() {
|
||||||
cycle_count: args.cycle_count,
|
cycle_count: args.cycle_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tile_window: Option<Box<dyn Renderer>> = if args.tile_window {
|
let tile_window: Option<Box<dyn Renderer<u32>>> = if args.tile_window {
|
||||||
Some(Box::new(WindowRenderer::new(factor, None)))
|
Some(Box::new(WindowRenderer::new(factor, None)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -132,7 +132,7 @@ fn create_audio_output() -> (AudioOutput, Stream) {
|
||||||
|
|
||||||
let sample_rate = config.sample_rate().0;
|
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
|
let stream = device
|
||||||
.build_output_stream(
|
.build_output_stream(
|
||||||
|
@ -183,7 +183,7 @@ impl WindowRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer for WindowRenderer {
|
impl Renderer<u32> for WindowRenderer {
|
||||||
fn prepare(&mut self, width: usize, height: usize) {
|
fn prepare(&mut self, width: usize, height: usize) {
|
||||||
self.width = width;
|
self.width = width;
|
||||||
self.height = height;
|
self.height = height;
|
||||||
|
|
|
@ -11,7 +11,7 @@ crate-type = ["cdylib", "rlib"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gb-emu-lib = { path = "../lib" }
|
gb-emu-lib = { path = "../lib", features = ["async"] }
|
||||||
nih_plug = { path = "../vendored/nih-plug", features = ["standalone"] }
|
nih_plug = { path = "../vendored/nih-plug", features = ["standalone"] }
|
||||||
baseview = { path = "../vendored/baseview" }
|
baseview = { path = "../vendored/baseview" }
|
||||||
pixels = "0.11.0"
|
pixels = "0.11.0"
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl Plugin for GameboyEmu {
|
||||||
};
|
};
|
||||||
let (sender, receiver) = channel::<EmulatorMessage>();
|
let (sender, receiver) = channel::<EmulatorMessage>();
|
||||||
|
|
||||||
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();
|
let (renderer, frame_receiver) = EmulatorRenderer::new();
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
async = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
async-ringbuf = "0.1.2"
|
async-ringbuf = "0.1.2"
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub enum RomFile {
|
||||||
Raw(Vec<u8>),
|
Raw(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
pub trait Renderer<Format: From<Colour>>: Send {
|
pub trait Renderer<Format: From<Colour>>: Send {
|
||||||
fn prepare(&mut self, width: usize, height: usize);
|
fn prepare(&mut self, width: usize, height: usize);
|
||||||
|
|
||||||
|
@ -25,26 +26,43 @@ pub trait Renderer<Format: From<Colour>>: Send {
|
||||||
fn set_rumble(&mut self, _rumbling: bool) {}
|
fn set_rumble(&mut self, _rumbling: bool) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "async"))]
|
||||||
|
pub trait Renderer<Format: From<Colour>> {
|
||||||
|
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 struct AudioOutput {
|
||||||
pub sample_rate: f32,
|
pub sample_rate: f32,
|
||||||
pub send_rb: AsyncHeapProducer<[f32; 2]>,
|
pub send_rb: AsyncHeapProducer<[f32; 2]>,
|
||||||
|
pub wait_for_output: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AudioOutput {
|
impl AudioOutput {
|
||||||
pub fn new(sample_rate: f32) -> (Self, AsyncHeapConsumer<[f32; 2]>) {
|
pub fn new(sample_rate: f32, wait_for_output: bool) -> (Self, AsyncHeapConsumer<[f32; 2]>) {
|
||||||
let (mut output, rx) = Self::new_unfilled(sample_rate);
|
let (mut output, rx) = Self::new_unfilled(sample_rate, wait_for_output);
|
||||||
|
|
||||||
executor::block_on(
|
executor::block_on(
|
||||||
output
|
output
|
||||||
.send_rb
|
.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();
|
.unwrap();
|
||||||
|
|
||||||
(output, rx)
|
(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_len = sample_rate as usize / (60 * 2);
|
||||||
|
|
||||||
let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len);
|
let rb = AsyncHeapRb::<[f32; 2]>::new(rb_len);
|
||||||
|
@ -54,6 +72,7 @@ impl AudioOutput {
|
||||||
Self {
|
Self {
|
||||||
sample_rate,
|
sample_rate,
|
||||||
send_rb,
|
send_rb,
|
||||||
|
wait_for_output,
|
||||||
},
|
},
|
||||||
rx,
|
rx,
|
||||||
)
|
)
|
||||||
|
|
|
@ -145,7 +145,10 @@ impl<ColourFormat: From<Colour> + Clone> Cpu<ColourFormat> {
|
||||||
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
self.set_or_clear_flag(Flags::Zero, result == 0x0);
|
||||||
self.set_or_clear_flag(
|
self.set_or_clear_flag(
|
||||||
Flags::HalfCarry,
|
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,
|
> 0xF,
|
||||||
);
|
);
|
||||||
result
|
result
|
||||||
|
|
|
@ -122,7 +122,11 @@ impl Apu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_audio(&mut self) {
|
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(
|
executor::block_on(
|
||||||
self.output
|
self.output
|
||||||
|
|
Loading…
Reference in a new issue