From c1deb55e2dfb410aeeb9b6b42e195c9923aa8bfb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 8 Oct 2023 11:25:29 +0100
Subject: [PATCH] feat: support for zip files Making use of the newly added
 `buildRomData()` method.

---
 CHANGELOG.md               |  2 +-
 frontends/web/package.json |  2 ++
 frontends/web/ts/gb.ts     | 16 +++++++++++++++-
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7fb1fbe9..29b96e5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-*
+* Support for Zip file in Web frontend
 
 ### Changed
 
diff --git a/frontends/web/package.json b/frontends/web/package.json
index 9827d355..eb9e9644 100644
--- a/frontends/web/package.json
+++ b/frontends/web/package.json
@@ -23,8 +23,10 @@
         "@types/react-dom": "^18.2.11",
         "@typescript-eslint/eslint-plugin": "^6.7.4",
         "@typescript-eslint/parser": "^6.7.4",
+        "buffer": "^6.0.3",
         "emukit": "^0.9.2",
         "eslint": "^8.51.0",
+        "jszip": "^3.10.1",
         "nodemon": "^3.0.1",
         "parcel": "^2.9.3",
         "prettier": "^3.0.3",
diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index b77a7474..a7a5a68e 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -1,3 +1,4 @@
+import { loadAsync } from "jszip";
 import {
     AudioSpecs,
     base64ToBuffer,
@@ -594,7 +595,7 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
     }
 
     get romExts(): string[] {
-        return ["gb", "gbc"];
+        return ["gb", "gbc", "zip"];
     }
 
     get pixelFormat(): PixelFormat {
@@ -785,6 +786,19 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
         this.gameBoy?.key_lift(keyCode);
     }
 
+    async buildRomData(file: File): Promise<Uint8Array> {
+        const arrayBuffer = await file.arrayBuffer();
+        let romData = new Uint8Array(arrayBuffer);
+
+        if (file.name.endsWith(".zip")) {
+            const zip = await loadAsync(romData);
+            const firstFile = Object.values(zip.files)[0];
+            romData = await firstFile.async("uint8array");
+        }
+
+        return romData;
+    }
+
     serializeState(): Uint8Array {
         if (!this.gameBoy) throw new Error("Unable to serialize state");
         return StateManager.save(this.gameBoy, SaveStateFormat.Bos);
-- 
GitLab