Skip to content
Snippets Groups Projects
Verified Commit 070f8f34 authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

fix: multuple frame draw during the same tick

This allows for a much more fluid draw of frames using the `present_vsync()`.
parent ae21656b
No related branches found
No related tags found
No related merge requests found
Pipeline #2193 passed
......@@ -227,10 +227,14 @@ impl Emulator {
let current_time = self.graphics.timer_subsystem.ticks();
let mut counter_cycles = pending_cycles;
let mut last_frame = 0xffffu16;
if current_time >= self.next_tick_time_i {
// re-starts the counter cycles with the number of pending cycles
// from the previous tick and the last frame with a dummy value
// meant to be overridden in case there's at least one new frame
// being drawn in the current tick
let mut counter_cycles = pending_cycles;
let mut last_frame = 0xffffu16;
// calculates the number of cycles that are meant to be the target
// for the current "tick" operation this is basically the current
// logic frequency divided by the visual one
......@@ -252,22 +256,13 @@ impl Emulator {
if self.system.ppu_mode() == PpuMode::VBlank
&& self.system.ppu_frame() != last_frame
{
// clears the graphics canvas, making sure that no garbage
// pixel data remaining in the pixel buffer, not doing this would
// create visual glitches in OSs like Mac OS X
self.graphics.canvas.clear();
// obtains the frame buffer of the Game Boy PPU and uses it
// to update the stream texture, copying it then to the canvas
// to update the stream texture, that will latter be copied
// to the canvas
let frame_buffer = self.system.frame_buffer().as_ref();
texture
.update(None, frame_buffer, DISPLAY_WIDTH * 3)
.unwrap();
self.graphics.canvas.copy(&texture, None, None).unwrap();
// presents the canvas effectively updating the screen
// information presented to the user
self.graphics.canvas.present();
// obtains the index of the current PPU frame, this value
// is going to be used to detect for new frame presence
......@@ -275,6 +270,26 @@ impl Emulator {
}
}
// in case there's at least one new frame that was drawn during
// during the current tick, then we need to flush it to the canvas,
// this separation between texture creation and canvas flush prevents
// resources from being over-used in situations where multiple frames
// are generated during the same tick cycle
if last_frame != 0xffffu16 {
// clears the graphics canvas, making sure that no garbage
// pixel data remaining in the pixel buffer, not doing this would
// create visual glitches in OSs like Mac OS X
self.graphics.canvas.clear();
// copies the texture that was created for the frame (during
// the loop part of the tick) to the canvas
self.graphics.canvas.copy(&texture, None, None).unwrap();
// presents the canvas effectively updating the screen
// information presented to the user
self.graphics.canvas.present();
}
// calculates the number of ticks that have elapsed since the
// last draw operation, this is critical to be able to properly
// operate the clock of the CPU in frame drop situations, meaning
......
......@@ -44,7 +44,12 @@ impl Graphics {
// creates an accelerated canvas to be used in the drawing
// then clears it so that is can be presented empty initially
let mut canvas = window.into_canvas().accelerated().build().unwrap();
let mut canvas = window
.into_canvas()
.accelerated()
.present_vsync()
.build()
.unwrap();
canvas.set_logical_size(width, height).unwrap();
canvas.clear();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment