From 17938014d1131ca43e1dd51111dae9bcaea3f809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Sat, 29 Apr 2023 17:13:17 +0100 Subject: [PATCH] chore: support for bg map attrs update --- src/ppu.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/src/ppu.rs b/src/ppu.rs index 35c3d2cd..7dd6b5b7 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -156,6 +156,27 @@ pub struct ObjectData { index: u8, } +impl ObjectData { + pub fn new() -> Self { + Self { + x: 0, + y: 0, + tile: 0, + palette: 0, + xflip: false, + yflip: false, + bg_over: false, + index: 0, + } + } +} + +impl Default for ObjectData { + fn default() -> Self { + Self::new() + } +} + impl Display for ObjectData { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( @@ -176,6 +197,24 @@ pub struct TileData { priority: bool, } +impl TileData { + pub fn new() -> Self { + Self { + palette: 0, + vram_bank: 0, + xflip: false, + yflip: false, + priority: false, + } + } +} + +impl Default for TileData { + fn default() -> Self { + Self::new() + } +} + impl Display for TileData { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( @@ -262,11 +301,11 @@ pub struct Ppu { palette_obj_1: Palette, /// The complete set of background palettes that are going to be - /// used in CGB emulation to provide the full set of colors. + /// used in CGB emulation to provide the full set of colors (CGB only). palettes_color_bg: [Palette; 8], /// The complete set of object/sprite palettes that are going to be - /// used in CGB emulation to provide the full set of colors. + /// used in CGB emulation to provide the full set of colors (CGB only). palettes_color_obj: [Palette; 8], /// The complete set of palettes in binary data so that they can @@ -274,9 +313,17 @@ pub struct Ppu { palettes: [u8; 3], /// The raw byte information (64 bytes) for the color palettes, - /// both the background and the objects one. + /// both the background and the objects one (CGB only). palettes_color: [[u8; 64]; 2], + /// The complete list of attributes for the first background + /// map that is located in 0x9800-0x9BFF (CGB only). + bg_map_attrs_0: [TileData; 1024], + + /// The complete list of attributes for the second background + /// map that is located in 0x9C00-0x9FFF (CGB only). + bg_map_attrs_1: [TileData; 1024], + /// The scroll Y register that controls the Y offset /// of the background. scy: u8, @@ -403,16 +450,7 @@ impl Ppu { vram_bank: 0x0, vram_offset: 0x0000, tiles: [Tile { buffer: [0u8; 64] }; TILE_COUNT], - obj_data: [ObjectData { - x: 0, - y: 0, - tile: 0, - palette: 0, - xflip: false, - yflip: false, - bg_over: false, - index: 0, - }; OBJ_COUNT], + obj_data: [ObjectData::default(); OBJ_COUNT], palette_colors: PALETTE_COLORS, palette: [[0u8; RGB_SIZE]; PALETTE_SIZE], palette_obj_0: [[0u8; RGB_SIZE]; PALETTE_SIZE], @@ -421,6 +459,8 @@ impl Ppu { palettes_color_obj: [[[0u8; RGB_SIZE]; PALETTE_SIZE]; 8], palettes: [0u8; 3], palettes_color: [[0u8; 64]; 2], + bg_map_attrs_0: [TileData::default(); 1024], + bg_map_attrs_1: [TileData::default(); 1024], scy: 0x0, scx: 0x0, wy: 0x0, @@ -637,6 +677,8 @@ impl Ppu { self.vram[(self.vram_offset + (addr & 0x1fff)) as usize] = value; if addr < 0x9800 { self.update_tile(addr, value); + } else if self.vram_bank == 0x1 { + self.update_bg_map_attrs(addr, value); } } 0xfe00..=0xfe9f => { @@ -872,6 +914,24 @@ impl Ppu { } } + fn update_bg_map_attrs(&mut self, addr: u16, value: u8) { + let bg_map = addr > 0x9bff; + let tile_index = if bg_map { addr - 0x9c00 } else { addr - 0x9800 }; + let tile_data = TileData { + palette: (value & 0x03 == 0x03) as u8, + vram_bank: (value & 0x08) >> 4, + xflip: value & 0x20 == 0x20, + yflip: value & 0x40 == 0x40, + priority: value & 0x80 == 0x80, + }; + let mut bg_map_attrs = if bg_map { + self.bg_map_attrs_1 + } else { + self.bg_map_attrs_0 + }; + bg_map_attrs[tile_index as usize] = tile_data; + } + pub fn registers(&self) -> PpuRegisters { PpuRegisters { scy: self.scy, -- GitLab