diff --git a/src/processor/gpu.rs b/src/processor/gpu.rs index 0ad6ca0..3fe0de5 100644 --- a/src/processor/gpu.rs +++ b/src/processor/gpu.rs @@ -25,6 +25,8 @@ pub struct GPU { mode_clock: usize, scanline: u8, tile_window: Option, + window_lc: u8, + has_window_been_enabled: bool, } impl GPU { @@ -54,6 +56,8 @@ impl GPU { mode_clock: 0, scanline: 0, tile_window, + window_lc: 0, + has_window_been_enabled: false, } } } @@ -158,6 +162,8 @@ impl CPU { fn exit_vblank(&mut self) { self.gpu.mode = DrawMode::Mode2; self.gpu.scanline = 0; + self.gpu.window_lc = 0; + self.gpu.has_window_been_enabled = false; if let Some(tile_window) = &mut self.gpu.tile_window { tile_window.draw_sprite_window(byte_to_palette(self.memory.get(0xFF47)), &self.memory); } @@ -210,7 +216,11 @@ impl CPU { if lcdc.bg_window_enable { self.render_scanline_bg(scanline, lcdc, bg_palette); if lcdc.window_enable { + if !self.gpu.has_window_been_enabled { + self.gpu.window_lc = scanline; + } self.render_scanline_window(scanline, lcdc, bg_palette); + self.gpu.has_window_been_enabled = true; } } else { for x in 0..WIDTH { @@ -227,6 +237,7 @@ impl CPU { let scroll_y = 0_u8.wrapping_sub(self.memory.get(0xFF42)); let scroll_x = 0_u8.wrapping_sub(self.memory.get(0xFF43)); self.render_tiles( + scanline, scanline, &lcdc.bg_tilemap, &lcdc.tile_area, @@ -241,15 +252,23 @@ impl CPU { let pos_y = self.memory.get(0xFF4A); // subtracting 7 to get the Real Number... let pos_x = self.memory.get(0xFF4B); - self.render_tiles( - scanline, - &lcdc.window_tilemap, - &lcdc.tile_area, - palette, - pos_x.wrapping_sub(7), - pos_y, - false, - ); + + if pos_y < 143 && pos_x < 166 { + // window is on screen + self.render_tiles( + scanline, + self.gpu.window_lc, + &lcdc.window_tilemap, + &lcdc.tile_area, + palette, + pos_x.wrapping_sub(7), + pos_y, + false, + ); + + self.gpu.window_lc = self.gpu.window_lc.wrapping_add(1); + self.gpu.has_window_been_enabled = true; + } } fn render_scanline_obj(&mut self, scanline: u8, lcdc: &LCDC, bg_palette: Palette) { @@ -332,6 +351,7 @@ impl CPU { fn render_tiles( &mut self, scanline: u8, + draw_from: u8, tilemap: &TilemapArea, tiledata: &TiledataArea, palette: Palette, @@ -339,7 +359,7 @@ impl CPU { offset_y: u8, wrap: bool, ) { - let (tile_line_y, did_wrap_y) = scanline.overflowing_sub(offset_y); + let (tile_line_y, did_wrap_y) = draw_from.overflowing_sub(offset_y); if did_wrap_y && !wrap { return; }