This commit is contained in:
Alex Janka 2023-03-26 21:33:09 +11:00
parent 0636cb7dc3
commit 37fbdb0ed0
7 changed files with 82 additions and 34 deletions

View file

@ -115,6 +115,7 @@ impl Plugin for GameboyEmu {
context: &mut impl ProcessContext<Self>,
) -> ProcessStatus {
if let Some(ref mut vars) = self.vars {
nih_warn!("processing audio...");
while let Some(event) = context.next_event() {
if let Some(Basic(as_bytes)) = event.as_midi() {
match event {
@ -182,21 +183,31 @@ impl Plugin for GameboyEmu {
}
}
}
nih_warn!("...finished processing note events");
if buffer.channels() != 2 {
nih_warn!("literally just panicking because there number of channels != 2 and if this is the problem you are literally stupid");
panic!()
}
nih_warn!("...not stupid");
for sample in buffer.iter_samples() {
if vars.rx.is_empty() {
nih_warn!("...rx empty: running until buffer full");
vars.emulator_core.run_until_buffer_full();
nih_warn!("...buffer full");
}
if let Some(a) = executor::block_on(vars.rx.pop()) {
for (source, dest) in a.iter().zip(sample) {
*dest = *source;
}
}
}
vars.emulator_core.run_until_buffer_full();
} else {
nih_warn!("...could not rx audio from emulator")
}
}
nih_warn!("...running emulator until buffer is full again");
vars.emulator_core.run_until_buffer_full();
nih_warn!("...finished with processing audio");
} else {
nih_warn!("processing audio before emulator init");
while context.next_event().is_some() {}
}
self.update_save_state();
@ -243,8 +254,11 @@ impl Plugin for GameboyEmu {
let (window, frame_receiver, key_handler) = EmulatorRenderer::new();
*self.frame_receiver.lock().unwrap() = Some(frame_receiver);
*self.key_handler.lock().unwrap() = Some(key_handler);
*self
.frame_receiver
.lock()
.expect("could not lock frame receiver") = Some(frame_receiver);
*self.key_handler.lock().expect("could not lock key handler") = Some(key_handler);
let (serial_tx, gb_serial_rx) = mpsc::channel::<u8>();
let serial_target = SerialTarget::Custom {

View file

@ -23,6 +23,7 @@ pub struct Emulator {
impl Emulator {
pub fn new(frame_receiver: Arc<FrameReceiver>, joypad_sender: Arc<JoypadSender>) -> Self {
nih_warn!("new emulator rx/tx struct");
Self {
frame_receiver,
joypad_sender,
@ -75,18 +76,26 @@ impl Editor for Emulator {
}
fn size(&self) -> (u32, u32) {
nih_warn!("editor size");
((WIDTH * EXTRA_SCALE) as u32, (HEIGHT * EXTRA_SCALE) as u32)
}
fn set_scale_factor(&self, _factor: f32) -> bool {
nih_warn!("editor scale factor");
true
}
fn param_value_changed(&self, _id: &str, _normalized_value: f32) {}
fn param_value_changed(&self, _id: &str, _normalized_value: f32) {
nih_warn!("editor param value changed");
}
fn param_modulation_changed(&self, _id: &str, _modulation_offset: f32) {}
fn param_modulation_changed(&self, _id: &str, _modulation_offset: f32) {
nih_warn!("editor param modulator changed");
}
fn param_values_changed(&self) {}
fn param_values_changed(&self) {
nih_warn!("editor param valueS changed");
}
}
pub struct EmulatorWindow {
@ -132,7 +141,7 @@ fn init_pixbuf(info: WindowInfo, window: &mut Window) -> (Pixels, usize, Vec<[u8
physical_size.height,
SurfaceTexture::new(physical_size.width, physical_size.height, window),
)
.unwrap(),
.expect("could not init pixbuf"),
scale,
scaled_buf,
)
@ -140,9 +149,11 @@ fn init_pixbuf(info: WindowInfo, window: &mut Window) -> (Pixels, usize, Vec<[u8
impl WindowHandler for EmulatorWindow {
fn on_frame(&mut self, _window: &mut Window) {
nih_warn!("window frame event");
nih_warn!("rendering window frame");
if let Some(ref mut receiver) = *self.frame_receiver.lock().expect("failed to lock mutex") {
nih_warn!("...got frame receiver");
if let Some(ref buf) = receiver.try_iter().last() {
nih_warn!("...got frame");
if self.scale != 1 {
scale_buffer_in_place(buf, &mut self.scaled_buf, WIDTH, HEIGHT, self.scale);
}
@ -154,12 +165,15 @@ impl WindowHandler for EmulatorWindow {
{
pixel.copy_from_slice(source);
}
self.pix.render().unwrap();
self.pix
.render()
.expect("could not render pixbuf to window");
}
}
}
fn on_event(&mut self, window: &mut Window, event: baseview::Event) -> EventStatus {
nih_warn!("window event");
match event {
Event::Window(WindowEvent::Resized(info)) => {
(self.pix, self.scale, self.scaled_buf) = init_pixbuf(info, window);
@ -181,7 +195,9 @@ impl WindowHandler for EmulatorWindow {
if let Some(ref mut sender) =
*self.joypad_sender.lock().expect("failed to lock mutex")
{
sender.send((button, status)).unwrap();
sender
.send((button, status))
.expect("could not send button status");
}
EventStatus::Captured
} else {
@ -218,14 +234,19 @@ impl EmulatorRenderer {
}
impl Renderer<[u8; 4]> for EmulatorRenderer {
fn prepare(&mut self, _width: usize, _height: usize) {}
fn prepare(&mut self, _width: usize, _height: usize) {
nih_warn!("preparing emulator");
}
#[allow(unused_must_use)]
fn display(&mut self, buffer: &[[u8; 4]]) {
nih_warn!("sending frame from emulator thread");
self.tx.send(buffer.to_vec());
nih_warn!("...finished sending frame");
}
fn latest_joypad_state(&mut self) -> JoypadState {
nih_warn!("begin getting latest joypad state");
while let Ok((key, state)) = self.keys.try_recv() {
match key {
JoypadButtons::Down => self.joypad.down = state,
@ -238,6 +259,7 @@ impl Renderer<[u8; 4]> for EmulatorRenderer {
JoypadButtons::A => self.joypad.a = state,
}
}
nih_warn!("end getting latest joypad state");
self.joypad
}
}

View file

@ -147,21 +147,23 @@ where
}
pub fn run_until_buffer_full(&mut self) {
println!("hello from gameboy");
while !self.cpu.memory.is_audio_buffer_full() {
self.run();
}
println!("gooby from gameboy");
}
fn run_cycle(&mut self) {
let will_pause = unsafe { PAUSE_QUEUED };
let pause_enabled = unsafe { PAUSE_ENABLED };
// let will_pause = unsafe { PAUSE_QUEUED };
// let pause_enabled = unsafe { PAUSE_ENABLED };
self.cpu.exec_next();
if !pause_enabled && self.cpu.reg.pc >= 0x100 {
unsafe { PAUSE_ENABLED = true };
}
if will_pause {
pause_then_step();
}
// if !pause_enabled && self.cpu.reg.pc >= 0x100 {
// unsafe { PAUSE_ENABLED = true };
// }
// if will_pause {
// pause_then_step();
// }
}
fn process_messages(&mut self) {

View file

@ -331,7 +331,7 @@ where
pub fn increment_timers(&mut self, machine_cycles: u8) {
let steps = (machine_cycles as usize) * 4;
self.memory.camera.lock().unwrap().tick(steps);
// self.memory.camera.lock().unwrap().tick(steps);
let timer_return = self.memory.timers.tick(steps);
@ -359,12 +359,12 @@ where
.interrupts
.set_interrupt(Interrupt::LcdStat, gpu_interrupts.lcd_stat);
if gpu_interrupts.vblank {
let latest_state = self.memory.gpu.window.latest_joypad_state();
let joypad_interrupt = self.memory.update_pressed_keys(latest_state);
self.memory
.interrupts
.set_interrupt(Interrupt::Joypad, joypad_interrupt);
}
// if gpu_interrupts.vblank {
// let latest_state = self.memory.gpu.window.latest_joypad_state();
// let joypad_interrupt = self.memory.update_pressed_keys(latest_state);
// self.memory
// .interrupts
// .set_interrupt(Interrupt::Joypad, joypad_interrupt);
// }
}
}

View file

@ -147,8 +147,10 @@ impl Apu {
.collect(),
);
if self.buffer.len() >= CYCLES_PER_FRAME {
println!("finished 1 frame of audio... pushing...");
self.next_audio();
} else if !self.out_buffer.is_empty() {
println!("pushing remainder...");
self.push_audio();
}
}
@ -173,12 +175,17 @@ impl Apu {
self.out_buffer.len().min(self.output.send_rb.free_len())
};
if length > 0 {
executor::block_on(
self.output
.send_rb
.push_slice(&self.out_buffer.drain(..length).collect::<Vec<[f32; 2]>>()),
)
.unwrap();
.expect("APU: error sending audio to output ringbuffer");
} else {
println!("buffer already full - skipped filling");
}
println!("finished pushing audio");
}
pub fn is_buffer_full(&self) -> bool {

View file

@ -455,6 +455,8 @@ where
}
fn render_window(&mut self) {
println!("gpu sending frame");
self.window.display(&self.buffer);
println!("gpu finished sending frame");
}
}

View file

@ -204,11 +204,12 @@ impl Serial {
match &self.target {
SerialTarget::Stdout => {
print!("{}", self.output_byte as char);
stdout().flush().unwrap();
stdout().flush().expect("Serial: error sending to stdout");
}
SerialTarget::Custom { rx: _, tx } => {
if let Some(tx) = tx {
tx.send(self.output_byte).unwrap();
tx.send(self.output_byte)
.expect("Serial: error sending to custom tx");
}
}
SerialTarget::None => {}