diff --git a/src/ppu.rs b/src/ppu.rs index b4a0dfb..0f14dff 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -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, }