From 3d0c0ab4d071370f2ea7c90e212e0037b60f09f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Mon, 24 Jul 2023 23:54:03 +0100
Subject: [PATCH] chore: new reload operation Also fixed frame global memory
 issue in libretro.

---
 frontends/libretro/src/lib.rs |  8 ++++++--
 src/gb.rs                     | 15 +++++++++++++--
 src/rom.rs                    |  4 ++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs
index 202727ad..b081d5e9 100644
--- a/frontends/libretro/src/lib.rs
+++ b/frontends/libretro/src/lib.rs
@@ -11,7 +11,7 @@ use std::{
 use boytacean::{
     gb::{AudioProvider, GameBoy},
     pad::PadKey,
-    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, RGB1555_SIZE},
+    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE, RGB1555_SIZE},
     rom::Cartridge,
 };
 
@@ -31,6 +31,7 @@ const RETRO_DEVICE_JOYPAD: usize = 1;
 
 static mut EMULATOR: Option<GameBoy> = None;
 static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None;
+static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB155_SIZE] = [0x00; FRAME_BUFFER_RGB155_SIZE];
 
 static mut ENVIRONMENT_CALLBACK: Option<extern "C" fn(u32, *const c_void) -> bool> = None;
 static mut VIDEO_REFRESH_CALLBACK: Option<extern "C" fn(*const u8, c_uint, c_uint, usize)> = None;
@@ -176,6 +177,8 @@ pub extern "C" fn retro_deinit() {
 #[no_mangle]
 pub extern "C" fn retro_reset() {
     println!("retro_reset()");
+    let emulator = unsafe { EMULATOR.as_mut().unwrap() };
+    emulator.reload();
 }
 
 #[no_mangle]
@@ -348,8 +351,9 @@ pub extern "C" fn retro_run() {
 
     let frame_buffer = emulator.frame_buffer_rgb1555();
     unsafe {
+        FRAME_BUFFER.copy_from_slice(&frame_buffer);
         VIDEO_REFRESH_CALLBACK.unwrap()(
-            frame_buffer.as_ptr(),
+            FRAME_BUFFER.as_ptr(),
             DISPLAY_WIDTH as u32,
             DISPLAY_HEIGHT as u32,
             DISPLAY_WIDTH * RGB1555_SIZE,
diff --git a/src/gb.rs b/src/gb.rs
index b95a0999..dee5b7df 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -406,6 +406,13 @@ impl GameBoy {
         self.cpu.reset();
     }
 
+    pub fn reload(&mut self) {
+        let rom = self.rom().clone();
+        self.reset();
+        self.load(true);
+        self.load_cartridge(rom);
+    }
+
     pub fn clock(&mut self) -> u16 {
         let cycles = self.cpu_clock() as u16;
         let cycles_n = cycles / self.multiplier() as u16;
@@ -989,13 +996,17 @@ impl GameBoy {
         self.load_boot_file(BootRom::Cgb);
     }
 
+    pub fn load_cartridge(&mut self, rom: Cartridge) -> &mut Cartridge {
+        self.mmu().set_rom(rom);
+        self.mmu().rom()
+    }
+
     pub fn load_rom(&mut self, data: &[u8], ram_data: Option<&[u8]>) -> &mut Cartridge {
         let mut rom = Cartridge::from_data(data);
         if let Some(ram_data) = ram_data {
             rom.set_ram_data(ram_data)
         }
-        self.mmu().set_rom(rom);
-        self.mmu().rom()
+        self.load_cartridge(rom)
     }
 
     pub fn load_rom_file(&mut self, path: &str, ram_path: Option<&str>) -> &mut Cartridge {
diff --git a/src/rom.rs b/src/rom.rs
index c4cc5388..031285e4 100644
--- a/src/rom.rs
+++ b/src/rom.rs
@@ -599,6 +599,10 @@ impl Cartridge {
         self.ram_data = data.to_vec();
     }
 
+    pub fn clear_ram_data(&mut self) {
+        self.ram_data = vec![0u8; self.ram_data.len()];
+    }
+
     pub fn description(&self, column_length: usize) -> String {
         let name_l = format!("{:width$}", "Name", width = column_length);
         let type_l = format!("{:width$}", "Type", width = column_length);
-- 
GitLab