Fix tearing

This commit is contained in:
Franco Colmenarez 2023-07-09 12:09:09 -05:00
parent 60bcc39a74
commit 7bfe760a57
3 changed files with 30 additions and 13 deletions

View File

@ -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]) { pub fn run(&mut self, cpu_cycles: Cycles, frame_buffer: &mut [u8]) {
self.cpu.reset_cycles(); self.cpu.reset_cycles();
while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 { while self.cpu.get_cycles().to_t().0 <= cpu_cycles.0 {
self.cpu.run(&mut self.bus); self.tick(frame_buffer);
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); pub fn run_frame(&mut self, frame_buffer: &mut [u8]) {
if self.bus.double_speed_mode() { self.cpu.reset_cycles();
self.bus.timer.do_cycles(&mut self.bus.interrupts, Cycles(cycles.0 * 3.0)); 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()));
} }
} }

View File

@ -345,6 +345,10 @@ impl PPU {
} }
} }
pub fn lcd_y(&self) -> u8 {
self.lcd_y
}
pub fn set_vram_bank(&mut self, bank: u8) { pub fn set_vram_bank(&mut self, bank: u8) {
if self.cgb_mode { if self.cgb_mode {
self.vram_bank = bank & 1; self.vram_bank = bank & 1;

View File

@ -1,6 +1,5 @@
use crate::emulator::Emulator; use crate::emulator::Emulator;
use crate::frames::Frames; use crate::frames::Frames;
use crate::cpu::Cycles;
use crate::ppu::{WIDTH, HEIGHT}; use crate::ppu::{WIDTH, HEIGHT};
use log::error; use log::error;
@ -81,7 +80,7 @@ pub fn start_eventloop() {
*control_flow = ControlFlow::Exit *control_flow = ControlFlow::Exit
}, },
Event::MainEventsCleared => { Event::MainEventsCleared => {
emulator.run(Cycles(70224.0), pixels.get_frame()); emulator.run_frame(pixels.get_frame());
frame_counter.increment(); frame_counter.increment();
if frame_counter.elapsed_ms() >= 1000 { if frame_counter.elapsed_ms() >= 1000 {
window.set_title(&format!("rmg-001 (FPS: {})", frame_counter.count())); window.set_title(&format!("rmg-001 (FPS: {})", frame_counter.count()));