diff --git a/src/processor/gpu.rs b/src/processor/gpu.rs index 723de66..2715744 100644 --- a/src/processor/gpu.rs +++ b/src/processor/gpu.rs @@ -1,6 +1,6 @@ use crate::{FACTOR, HEIGHT, WIDTH}; -use super::{clear_bit, get_bit, set_bit, set_or_clear_bit, CPU}; +use super::{as_signed, clear_bit, get_bit, set_bit, set_or_clear_bit, CPU}; #[derive(PartialEq)] enum DrawMode { @@ -20,6 +20,15 @@ enum TiledataArea { D8800, } +impl TiledataArea { + fn get_addr(&self, addr: u8) -> u16 { + match self { + TiledataArea::D8000 => 0x8000 + (addr as u16), + TiledataArea::D8800 => 0x8800_u16.wrapping_add_signed(as_signed(addr) as i16), + } + } +} + enum ObjSize { S8x8, S8x16, @@ -175,8 +184,8 @@ impl CPU { fn enter_vblank(&mut self, lcdc: &LCDC) { self.gpu.mode = DrawMode::VBlank; if lcdc.enable { - self.render_window(); - self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 0)); + self.render_window(); + self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 0)); } } @@ -221,7 +230,14 @@ impl CPU { let scroll_y = self.memory.get(0xFF42); let scroll_x = self.memory.get(0xFF43); let palette = byte_to_palette(self.memory.get(0xFF47)); - self.render_tiles(scanline, &lcdc.bg_tilemap, palette); + self.render_tiles( + scanline, + &lcdc.bg_tilemap, + &lcdc.tile_area, + palette, + scroll_x, + scroll_y, + ); } fn render_scanline_window(&mut self, _scanline: u8, _lcdc: &LCDC) { @@ -235,12 +251,25 @@ impl CPU { fn render_scanline_obj(&mut self, _scanline: u8, _lcdc: &LCDC) {} - fn render_tiles(&mut self, scanline: u8, tilemap: &TilemapArea, palette: Palette) { - let tile_row = (scanline as usize) / 8; + fn render_tiles( + &mut self, + scanline: u8, + tilemap: &TilemapArea, + tiledata: &TiledataArea, + palette: Palette, + offset_x: u8, + offset_y: u8, + ) { + let tile_line = (scanline as usize) + (offset_y as usize); + let tile_row = tile_line / 8; + let tile_px = ((tile_line as u16) % 8) * 2; let row_addr = (tile_row * 32) as u16 + get_tilemap_offset(tilemap); for x in 0..32 { - let lsbs = self.memory.get(row_addr + (x * 2)); - let msbs = self.memory.get(row_addr + (x * 2) + 1); + let tile_addr = self.memory.get(row_addr + x) + tile_px as u8; + let lsbs = self.memory.get(tiledata.get_addr(tile_addr)); + let msbs = self.memory.get(tiledata.get_addr(tile_addr + 1)); + // let lsbs = self.memory.get(row_addr + tile_px + (x * 2)); + // let msbs = self.memory.get(row_addr + tile_px + (x * 2) + 1); for px_x in 0..8 { let lsb = get_bit(lsbs, px_x); let msb = get_bit(msbs, px_x);