From 870da344076f8ff32f364e0f0d6aa2769e997b1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Fri, 2 Aug 2024 21:35:57 +0100
Subject: [PATCH] chore: support for BOSC in web

Created automatic inference of format from magic number.
Extracts BOS data from BOSC files to be used in web.
---
 frontends/web/ts/gb.ts |  4 ++--
 src/state.rs           | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index f57b96a7..9ec6080e 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -720,7 +720,7 @@ export class GameboyEmulator extends EmulatorLogic implements Emulator {
 
     serializeState(): Uint8Array {
         if (!this.gameBoy) throw new Error("Unable to serialize state");
-        return StateManager.save_wa(this.gameBoy, SaveStateFormat.Bos);
+        return StateManager.save_wa(this.gameBoy);
     }
 
     unserializeState(data: Uint8Array) {
@@ -729,7 +729,7 @@ export class GameboyEmulator extends EmulatorLogic implements Emulator {
     }
 
     buildState(index: number, data: Uint8Array): SaveState {
-        const state = StateManager.read_bos_wa(data);
+        const state = StateManager.read_bos_auto_wa(data);
         return {
             index: index,
             timestamp: Number(state.timestamp_wa()),
diff --git a/src/state.rs b/src/state.rs
index 31555959..ef44956f 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1669,6 +1669,36 @@ impl StateManager {
         Ok(())
     }
 
+    pub fn read_bos_auto(data: &[u8]) -> Result<BosState, Error> {
+        let data = &mut Cursor::new(data.to_vec());
+        let format = if BoscState::is_bosc(data) {
+            SaveStateFormat::Bosc
+        } else if BosState::is_bos(data) {
+            SaveStateFormat::Bos
+        } else if BessState::is_bess(data) {
+            return Err(Error::CustomError(String::from(
+                "Incompatible save state file format (BESS)",
+            )));
+        } else {
+            return Err(Error::CustomError(String::from(
+                "Unknown save state file format",
+            )));
+        };
+        match format {
+            SaveStateFormat::Bosc => {
+                let mut state = BoscState::default();
+                state.read(data);
+                Ok(state.bos)
+            }
+            SaveStateFormat::Bos => {
+                let mut state = BosState::default();
+                state.read(data);
+                Ok(state)
+            }
+            _ => unreachable!(),
+        }
+    }
+
     pub fn read_bosc(data: &[u8]) -> Result<BoscState, Error> {
         let data = &mut Cursor::new(data.to_vec());
         let mut state = BoscState::default();
@@ -1743,6 +1773,10 @@ impl StateManager {
         Self::load(data, gb, format).map_err(|e| e.to_string())
     }
 
+    pub fn read_bos_auto_wa(data: &[u8]) -> Result<BosState, String> {
+        Self::read_bos_auto(data).map_err(|e| e.to_string())
+    }
+
     pub fn read_bosc_wa(data: &[u8]) -> Result<BoscState, String> {
         Self::read_bosc(data).map_err(|e| e.to_string())
     }
-- 
GitLab