window internal lc

This commit is contained in:
Alex Janka 2023-02-10 09:26:26 +11:00
parent cf67c8a501
commit 63f98a5ec4

View file

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