From 7bfe760a57fca33e5084da04edbf0dcf6fe76d41 Mon Sep 17 00:00:00 2001 From: Franco Colmenarez Date: Sun, 9 Jul 2023 12:09:09 -0500 Subject: [PATCH] Fix tearing --- src/emulator.rs | 36 +++++++++++++++++++++++++----------- src/ppu.rs | 4 ++++ src/render.rs | 3 +-- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/emulator.rs b/src/emulator.rs index e21d4b7..a1934c6 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -109,21 +109,35 @@ impl Emulator { } } + fn tick(&mut self, frame_buffer: &mut [u8]) { + self.cpu.run(&mut self.bus); + let cycles = self.cpu.get_last_op_cycles().to_t(); + self.bus.ppu.do_cycles(&mut self.bus.interrupts, cycles, frame_buffer); + self.bus.sound.do_cycles(cycles); + self.bus.timer.do_cycles(&mut self.bus.interrupts, cycles); + if self.bus.double_speed_mode() { + self.bus.timer.do_cycles(&mut self.bus.interrupts, Cycles(cycles.0 * 3.0)); + } + + // 1 CPU cycle = 238.42ns + // thread::sleep(time::Duration::from_nanos((self.cpu.get_last_op_cycles().0 * 238).try_into().unwrap())); + } + pub fn run(&mut self, cpu_cycles: Cycles, frame_buffer: &mut [u8]) { self.cpu.reset_cycles(); while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 { - self.cpu.run(&mut self.bus); - let cycles = self.cpu.get_last_op_cycles().to_t(); - self.bus.ppu.do_cycles(&mut self.bus.interrupts, cycles, frame_buffer); - self.bus.sound.do_cycles(cycles); - self.bus.timer.do_cycles(&mut self.bus.interrupts, cycles); - if self.bus.double_speed_mode() { - self.bus.timer.do_cycles(&mut self.bus.interrupts, Cycles(cycles.0 * 3.0)); + self.tick(frame_buffer); + } + } + + pub fn run_frame(&mut self, frame_buffer: &mut [u8]) { + self.cpu.reset_cycles(); + let mut frame_started = true; + while self.bus.ppu.lcd_y() < 144 || frame_started { + self.tick(frame_buffer); + if self.bus.ppu.lcd_y() == 0 { + frame_started = false; } - - // 1 CPU cycle = 238.42ns - // thread::sleep(time::Duration::from_nanos((self.cpu.get_last_op_cycles().0 * 238).try_into().unwrap())); - } } diff --git a/src/ppu.rs b/src/ppu.rs index 7bc433b..a939372 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -345,6 +345,10 @@ impl PPU { } } + pub fn lcd_y(&self) -> u8 { + self.lcd_y + } + pub fn set_vram_bank(&mut self, bank: u8) { if self.cgb_mode { self.vram_bank = bank & 1; diff --git a/src/render.rs b/src/render.rs index f2e640c..ba9cba4 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,6 +1,5 @@ use crate::emulator::Emulator; use crate::frames::Frames; -use crate::cpu::Cycles; use crate::ppu::{WIDTH, HEIGHT}; use log::error; @@ -81,7 +80,7 @@ pub fn start_eventloop() { *control_flow = ControlFlow::Exit }, Event::MainEventsCleared => { - emulator.run(Cycles(70224.0), pixels.get_frame()); + emulator.run_frame(pixels.get_frame()); frame_counter.increment(); if frame_counter.elapsed_ms() >= 1000 { window.set_title(&format!("rmg-001 (FPS: {})", frame_counter.count()));