From cb81915f53fb6b73a8fb248e24dee30de59494b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Tue, 8 Aug 2023 15:10:46 +0100
Subject: [PATCH] fix: issues pending in GBC state saving Made VRAM update
 possible.

---
 src/gb.rs    |  2 +-
 src/ppu.rs   | 56 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/state.rs |  4 ++--
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/src/gb.rs b/src/gb.rs
index 0f9b1613..3d5047f3 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -520,7 +520,7 @@ impl GameBoy {
         match self.mode() {
             GameBoyMode::Dmg => self.load_dmg(boot),
             GameBoyMode::Cgb => self.load_cgb(boot),
-            GameBoyMode::Sgb => todo!(),
+            GameBoyMode::Sgb => unimplemented!(),
         }
     }
 
diff --git a/src/ppu.rs b/src/ppu.rs
index 8686cc96..43234b92 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -1015,10 +1015,35 @@ impl Ppu {
         &self.vram
     }
 
+    pub fn vram_dmg(&self) -> &[u8] {
+        &self.vram[0..VRAM_SIZE_DMG]
+    }
+
+    pub fn vram_cgb(&self) -> &[u8] {
+        &self.vram[0..VRAM_SIZE_CGB]
+    }
+
+    pub fn vram_device(&self) -> &[u8] {
+        match self.gb_mode {
+            GameBoyMode::Dmg => self.vram_dmg(),
+            GameBoyMode::Cgb => self.vram_cgb(),
+            GameBoyMode::Sgb => self.vram_dmg(),
+        }
+    }
+
+    pub fn set_vram(&mut self, value: &[u8]) {
+        self.vram[0..value.len()].copy_from_slice(value);
+        self.update_vram();
+    }
+
     pub fn hram(&self) -> &[u8; HRAM_SIZE] {
         &self.hram
     }
 
+    pub fn set_hram(&mut self, value: [u8; HRAM_SIZE]) {
+        self.hram = value;
+    }
+
     pub fn tiles(&self) -> &[Tile; TILE_COUNT] {
         &self.tiles
     }
@@ -1134,6 +1159,28 @@ impl Ppu {
         println!("{}", self.tiles[tile_index]);
     }
 
+    /// Updates the internal PPU state (calculated values) according
+    /// to the VRAM values, this should be called whenever the VRAM
+    /// is replaced.
+    pub fn update_vram(&mut self) {
+        let vram_banks = if self.gb_mode == GameBoyMode::Cgb {
+            2u16
+        } else {
+            1u16
+        };
+        for vram_bank in 0..vram_banks {
+            let vram_offset = vram_bank * 0x2000;
+            for addr in 0x8000..=0x9fff {
+                let value = self.vram[(vram_offset + (addr & 0x1fff)) as usize];
+                if addr < 0x9800 {
+                    self.update_tile(addr, value);
+                } else if vram_bank == 0x1 {
+                    self.update_bg_map_attrs(addr, value);
+                }
+            }
+        }
+    }
+
     /// Updates the tile structure with the value that has
     /// just been written to a location on the VRAM associated
     /// with tiles.
@@ -1843,11 +1890,10 @@ impl Ppu {
         for index in 0..2 {
             let palette = &mut palettes[index];
             let palette_color = &palettes_color[index];
-
-            for palette_index in (0..palette.len()).step_by(8) {
+            for palette_index in 0..palette.len() {
                 Self::compute_color_palette(
-                    &mut palette[palette_index / 8],
-                    &palette_color[palette_index..palette_index + 8]
+                    &mut palette[palette_index],
+                    &palette_color[palette_index * 8..(palette_index + 1) * 8]
                         .try_into()
                         .unwrap(),
                 );
@@ -1860,7 +1906,7 @@ impl Ppu {
     /// represent the 4 colors of the palette in the RGB555 format.
     fn compute_color_palette(palette: &mut Palette, palette_color: &[u8; 8]) {
         for color_index in 0..palette.len() {
-            palette[color_index as usize] = Self::rgb555_to_rgb888(
+            palette[color_index] = Self::rgb555_to_rgb888(
                 palette_color[color_index * 2],
                 palette_color[color_index * 2 + 1],
             );
diff --git a/src/state.rs b/src/state.rs
index 58b8d70d..9e2f968e 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -765,7 +765,7 @@ impl State for BeesCore {
             gb.mmu().read_many(0xff00, 128).try_into().unwrap(),
         );
         core.ram.fill_buffer(gb.mmu().ram());
-        core.vram.fill_buffer(&gb.mmu().read_many(0x8000, 0x2000));
+        core.vram.fill_buffer(gb.ppu().vram_device());
         core.mbc_ram.fill_buffer(gb.rom_i().ram_data());
         core.oam.fill_buffer(&gb.mmu().read_many(0xfe00, 0x00a0));
         core.hram.fill_buffer(&gb.mmu().read_many(0xff80, 0x007f));
@@ -792,7 +792,7 @@ impl State for BeesCore {
         gb.mmu().write_many(0xff00, &self.io_registers);
 
         gb.mmu().set_ram(self.ram.buffer.to_vec());
-        gb.mmu().write_many(0x8000, &self.vram.buffer);
+        gb.ppu().set_vram(&self.vram.buffer);
         gb.rom().set_ram_data(&self.mbc_ram.buffer);
         gb.mmu().write_many(0xfe00, &self.oam.buffer);
         gb.mmu().write_many(0xff80, &self.hram.buffer);
-- 
GitLab