chore(ppu): refactor behaviour w.r.t window enabling

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-10-20 04:48:20 -03:00
parent da83032e24
commit d9f1d661ae
1 changed files with 33 additions and 89 deletions

View File

@ -81,6 +81,12 @@ impl Ppu {
PpuMode::OamScan => {
// Cycles 1 -> 80
if self.dot >= 80 {
self.x_pos = 0;
self.scanline_start = true;
self.to_discard = 0;
self.fifo.back.clear();
self.fifo.obj.clear();
self.stat.set_mode(PpuMode::Drawing);
}
@ -105,21 +111,14 @@ impl Ppu {
// Increment Window line counter if scanline had any window pixels on it
// only increment once per scanline though
if self.win_stat.should_draw() {
self.fetch.back.window_line.increment();
if self.win_stat.enabled {
self.fetch.back.wl_count += 1;
}
self.x_pos = 0;
self.scanline_start = true;
self.to_discard = 0;
self.fetch.hblank_reset();
self.win_stat.hblank_reset();
self.win_stat.enabled = false;
self.obj_buffer.clear();
self.fifo.back.clear();
self.fifo.obj.clear();
self.stat.set_mode(PpuMode::HBlank);
}
}
@ -144,9 +143,10 @@ impl Ppu {
self.int.set_vblank(true);
// Reset Window Line Counter in Fetcher
self.fetch.vblank_reset();
self.fetch.back.wl_count = 0;
// Reset WY=LY coincidence flag
self.win_stat.vblank_reset();
self.win_stat.coincidence = false;
if self.stat.vblank_int() {
// Enable Vblank LCDStat Interrupt
@ -203,9 +203,8 @@ impl Ppu {
return;
}
if !self.win_stat.coincidence() && self.scan_dot == 0 {
self.win_stat
.set_coincidence(self.pos.line_y == self.pos.window_y);
if !self.win_stat.coincidence && self.scan_dot == 0 {
self.win_stat.coincidence = self.pos.line_y == self.pos.window_y;
}
let obj_height = self.ctrl.obj_size().size();
@ -317,25 +316,12 @@ impl Ppu {
}
}
if self.ctrl.window_enabled()
&& !self.win_stat.should_draw()
&& self.win_stat.coincidence()
&& self.x_pos as i16 >= self.pos.window_x as i16 - 7
{
self.win_stat.set_should_draw(true);
self.fetch.back.reset();
self.fetch.x_pos = 0;
self.fifo.back.clear();
}
if self.fetch.back.is_enabled() {
match self.fetch.back.state {
TileNumber => {
let x_pos = self.fetch.x_pos;
self.fetch
.back
.should_render_window(self.win_stat.should_draw());
self.fetch.back.should_render_window(self.win_stat.enabled);
let addr = self.fetch.bg_tile_num_addr(&self.ctrl, &self.pos, x_pos);
@ -383,7 +369,7 @@ impl Ppu {
self.scanline_start = false;
}
if self.to_discard > 0 && !self.fifo.back.is_empty() {
if !self.win_stat.enabled && self.to_discard > 0 && !self.fifo.back.is_empty() {
let _ = self.fifo.back.pop_front();
self.to_discard -= 1;
@ -401,6 +387,17 @@ impl Ppu {
self.x_pos += 1;
}
if self.ctrl.window_enabled()
&& !self.win_stat.enabled
&& self.win_stat.coincidence
&& self.x_pos as i16 >= self.pos.window_x as i16 - 7
{
self.win_stat.enabled = true;
self.fetch.back.reset();
self.fetch.x_pos = 0;
self.fifo.back.clear();
}
}
}
@ -653,10 +650,6 @@ impl PixelFetcher {
self.x_pos = 0;
}
fn vblank_reset(&mut self) {
self.back.vblank_reset();
}
fn bg_tile_num_addr(&self, control: &LCDControl, pos: &ScreenPosition, x_pos: u8) -> u16 {
let line_y = pos.line_y;
let scroll_y = pos.scroll_y;
@ -676,7 +669,7 @@ impl PixelFetcher {
let scx_offset = if is_window { 0 } else { scroll_x / 8 };
let y_offset = if is_window {
self.back.window_line.count() as u16 / 8
self.back.wl_count as u16 / 8
} else {
((line_y as u16 + scroll_y as u16) & 0xFF) / 8
};
@ -700,7 +693,7 @@ impl PixelFetcher {
};
let offset = if is_window {
self.back.window_line.count() as u16 % 8
self.back.wl_count as u16 % 8
} else {
(line_y as u16 + scroll_y as u16) % 8
};
@ -762,7 +755,7 @@ trait Fetcher {
struct BackgroundFetcher {
state: FetcherState,
tile: TileBuilder,
window_line: WindowLineCounter,
wl_count: u8,
is_window_tile: bool,
enabled: bool,
}
@ -787,10 +780,6 @@ impl BackgroundFetcher {
fn is_enabled(&self) -> bool {
self.enabled
}
fn vblank_reset(&mut self) {
self.window_line.vblank_reset();
}
}
impl Fetcher for BackgroundFetcher {
@ -818,7 +807,7 @@ impl Default for BackgroundFetcher {
state: Default::default(),
tile: Default::default(),
is_window_tile: Default::default(),
window_line: Default::default(),
wl_count: Default::default(),
enabled: true,
}
}
@ -846,25 +835,6 @@ impl Fetcher for ObjectFetcher {
}
}
#[derive(Debug, Default)]
struct WindowLineCounter {
count: u8,
}
impl WindowLineCounter {
fn increment(&mut self) {
self.count += 1;
}
fn vblank_reset(&mut self) {
self.count = 0;
}
fn count(&self) -> u8 {
self.count
}
}
#[derive(Debug, Clone, Copy)]
enum FetcherState {
TileNumber,
@ -959,31 +929,5 @@ struct WindowStatus {
coincidence: bool,
/// This will be true if the conditions which tell the PPU to start
/// drawing from the window tile map is true
should_draw: bool,
}
impl WindowStatus {
fn should_draw(&self) -> bool {
self.should_draw
}
fn coincidence(&self) -> bool {
self.coincidence
}
fn set_should_draw(&mut self, value: bool) {
self.should_draw = value;
}
fn set_coincidence(&mut self, value: bool) {
self.coincidence = value;
}
fn hblank_reset(&mut self) {
self.should_draw = false;
}
fn vblank_reset(&mut self) {
self.coincidence = false;
}
enabled: bool,
}