From 74691a2403e2dbd34dabd2edfc1e978a6332b1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Sun, 30 Apr 2023 10:51:57 +0100 Subject: [PATCH] chore: initial validated color palette work The background attributes seem to be failing. --- frontends/sdl/src/main.rs | 4 +-- src/ppu.rs | 63 ++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs index 0e423926..95066f5c 100644 --- a/frontends/sdl/src/main.rs +++ b/frontends/sdl/src/main.rs @@ -465,7 +465,8 @@ struct Args { #[arg(short, long, default_value_t = String::from("printer"))] device: String, - #[arg(short, long, default_value_t = String::from("../../res/roms.prop/tetris_dx.gbc"))] + // TODO: change this to emulator.load_rom(Some("../../res/roms/demo/pocket.gb")); + #[arg(short, long, default_value_t = String::from("/Users/joamag/Desktop/repo.other/boytacean/res/roms.prop/tetris_dx.gbc"))] rom_path: String, } @@ -491,7 +492,6 @@ fn main() { let mut emulator = Emulator::new(game_boy); emulator.start(SCREEN_SCALE); emulator.load_rom(Some(&args.rom_path)); - //emulator.load_rom(Some("../../res/roms/demo/pocket.gb")); emulator.toggle_palette(); emulator.run(); } diff --git a/src/ppu.rs b/src/ppu.rs index d0b349c3..4e42b10a 100644 --- a/src/ppu.rs +++ b/src/ppu.rs @@ -745,15 +745,16 @@ impl Ppu { } // 0xFF69 — BCPD/BGPD (CGB only) 0xff69 => { - let mut palette_color = self.palettes_color[0]; - palette_color[self.palette_address_bg as usize] = value; - let palette_index = self.palette_address_bg / 8; - Self::compute_palette_color( - &mut self.palettes_color_bg[palette_index as usize], - &palette_color, - palette_index, - ); + + // @TODO: we can optimize this code to make it so that only + // the target color of the target palette is updated, this + // should provide us with a 4x speedup in computation + + let palette_color = &mut self.palettes_color[0]; + palette_color[self.palette_address_bg as usize] = value; + let palette = &mut self.palettes_color_bg[palette_index as usize]; + Self::compute_palette_color(palette, palette_color, palette_index); if self.auto_increment_bg { self.palette_address_bg = (self.palette_address_bg + 1) & 0x3f; @@ -766,10 +767,13 @@ impl Ppu { } // 0xFF6B — OCPD/OBPD (CGB only) 0xff6b => { - self.palettes_color[1][self.palette_address_obj as usize] = value; - //@TODO: update palette object data accordingly for the given update - // index - should not be a problem - // compute_palette_color should probably be the name + let palette_index = self.palette_address_bg / 8; + + let palette_color = &mut self.palettes_color[1]; + palette_color[self.palette_address_bg as usize] = value; + let palette = &mut self.palettes_color_obj[palette_index as usize]; + Self::compute_palette_color(palette, palette_color, palette_index); + if self.auto_increment_obj { self.palette_address_obj = (self.palette_address_obj + 1) & 0x3f; } @@ -926,13 +930,13 @@ 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 mut bg_map_attrs = if bg_map { - self.bg_map_attrs_1 + let bg_map_attrs = if bg_map { + &mut self.bg_map_attrs_1 } else { - self.bg_map_attrs_0 + &mut self.bg_map_attrs_0 }; - let tile_data = bg_map_attrs[tile_index as usize].borrow_mut(); - tile_data.palette = (value & 0x03 == 0x03) as u8; + let tile_data: &mut TileData = bg_map_attrs[tile_index as usize].borrow_mut(); + tile_data.palette = value & 0x03; tile_data.vram_bank = (value & 0x08) >> 4; tile_data.vram_bank = (value & 0x08) >> 4; tile_data.xflip = value & 0x20 == 0x20; @@ -983,6 +987,14 @@ impl Ppu { // that control which background map is going to be used let mut map_offset: usize = if map { 0x1c00 } else { 0x1800 }; + // selects the correct background attributes map based on the bg map flag + // because the attributes are separated according to the map they represent + let bg_map_attrs = if map { + self.bg_map_attrs_1 + } else { + self.bg_map_attrs_0 + }; + // increments the map offset by the row offset multiplied by the number // of tiles in each row (32) map_offset += row_offset * 32; @@ -999,6 +1011,10 @@ impl Ppu { tile_index += 256; } + //@TODO: this is conditional to the CG mode!!! + let mut tile_attr = bg_map_attrs[tile_index]; + let mut palette = self.palettes_color_bg[tile_attr.palette as usize]; + // calculates the offset that is going to be used in the update of the color buffer // which stores Game Boy colors from 0 to 3 let mut color_offset = self.ly as usize * DISPLAY_WIDTH; @@ -1020,7 +1036,9 @@ impl Ppu { // obtains the current pixel data from the tile and // re-maps it according to the current palette let pixel = self.tiles[tile_index].get(x, y); - let color = self.palette_bg[pixel as usize]; + // TODO: make this color work!!! + //let color = self.palette_bg[pixel as usize]; + let color = palette[pixel as usize]; // updates the pixel in the color buffer, which stores // the raw pixel color information (unmapped) @@ -1035,7 +1053,7 @@ impl Ppu { x += 1; // in case the end of tile width has been reached then - // a new tile must be retrieved for plotting + // a new tile must be retrieved for rendering if x == TILE_WIDTH { // resets the tile X position to the base value // as a new tile is going to be drawn @@ -1051,6 +1069,9 @@ impl Ppu { if !self.bg_tile && tile_index < 128 { tile_index += 256; } + + tile_attr = bg_map_attrs[tile_index]; + palette = self.palettes_color_bg[tile_attr.palette as usize]; } } @@ -1271,8 +1292,8 @@ impl Ppu { } fn rgb555_to_rgb888(first: u8, second: u8) -> Pixel { - let r = first & 0x1f << 3; - let g = (first & 0xe0 >> 5 | (second & 0x03) << 3) << 3; + let r = (first & 0x1f) << 3; + let g = (((first & 0xe0) >> 5) | ((second & 0x03) << 3)) << 3; let b = ((second & 0x7c) >> 2) << 3; [r as u8, g as u8, b as u8] } -- GitLab