diff --git a/src/html/index.html b/src/html/index.html
index 3f0e484..4aa3f52 100644
--- a/src/html/index.html
+++ b/src/html/index.html
@@ -22,7 +22,7 @@
-
+
Click to Load ROM File
diff --git a/src/scripts/ui/controls/emulator.ts b/src/scripts/ui/controls/emulator.ts
index ee7e835..b3803f2 100644
--- a/src/scripts/ui/controls/emulator.ts
+++ b/src/scripts/ui/controls/emulator.ts
@@ -1,17 +1,89 @@
import { Chip8Emulator } from '../../emulator/emulator';
-const input = document.getElementById('file') as HTMLInputElement | null;
+const input = document.getElementById('file') as HTMLElement | null;
const resetRomBtn = document.getElementById('reset-rom-btn') as HTMLElement | null;
+async function getFileFromHandle(fileHandle: File | FileSystemFileHandle): Promise {
+ if (fileHandle instanceof FileSystemFileHandle) {
+ return await fileHandle.getFile();
+ } else {
+ return fileHandle;
+ }
+}
+
+async function handleFileInput(files: FileList | FileSystemFileHandle[], emulatorInstance: Chip8Emulator) {
+ let fileData = await getFileFromHandle(files[0]);
+
+ try {
+ const arrayBuffer = await fileData.arrayBuffer();
+ const romData = new Uint8Array(arrayBuffer);
+
+ emulatorInstance.loadRomFromData(romData);
+
+ } catch(error) {
+ return alert(`Error loading the ROM file.`);
+ }
+}
+
+function setNowPlayingRomName(romName: string) {
+ if (!input) return;
+ input.innerText = `Loaded ROM: ${romName}`;
+}
+
+async function handleFilePickerEvent(emulatorInstance: Chip8Emulator) {
+ const filePickerOptions: OpenFilePickerOptions = {
+ types: [
+ {
+ description: 'Chip-8 ROM files',
+ accept: {
+ 'application/octet-stream': ['.ch8', '.sc8', '.xo8'],
+ },
+ },
+ ],
+ multiple: false,
+ };
+
+ const fileHandle = await window.showOpenFilePicker(filePickerOptions);
+ await handleFileInput(fileHandle, emulatorInstance);
+
+ setNowPlayingRomName(fileHandle[0].name);
+}
+
+async function handleFilePickerEventFallback(emulatorInstance: Chip8Emulator) {
+ const fileInput = document.createElement('input');
+
+ fileInput.type = 'file';
+ fileInput.accept = '.ch8,.sc8,.xo8';
+ fileInput.style.display = 'none';
+
+ fileInput.addEventListener('change', async (event) => {
+ const target = event.target as HTMLInputElement;
+
+ if (target.files && target.files.length > 0) {
+ await handleFileInput(target.files, emulatorInstance);
+ setNowPlayingRomName(target.files[0].name);
+ }
+ });
+
+ document.body.appendChild(fileInput);
+ fileInput.click();
+ document.body.removeChild(fileInput);
+}
+
function initializeRomFileInputEventHandlers(emulatorInstance: Chip8Emulator) {
if (!input) return;
- input.addEventListener('change', async (event) => {
+ input.addEventListener('click', async () => {
try {
- await emulatorInstance.startEmulation(event as GenericEvent);
- input.blur();
+ if ('showOpenFilePicker' in window) {
+ await handleFilePickerEvent(emulatorInstance);
+ } else {
+ await handleFilePickerEventFallback(emulatorInstance);
+ }
} catch(error) {
- console.error(error);
+ if ((error as Error)?.name !== 'AbortError') {
+ return alert(`Error loading the ROM file.`);
+ }
}
});
}
@@ -28,21 +100,6 @@ function initializeResetRomButtonEventHandlers(emulatorInstance: Chip8Emulator)
});
}
-async function handleFileInput(files: Array, emulatorInstance: Chip8Emulator) {
- const fileHandle = files[0];
-
- try {
- const fileData = await fileHandle.getFile();
- const arrayBuffer = await fileData.arrayBuffer();
-
- const romData = new Uint8Array(arrayBuffer);
- emulatorInstance.loadRomFromData(romData);
-
- } catch(error) {
- return alert(`Error loading the ROM file.`);
- }
-}
-
function registerFileHandlerLoadRom(emulatorInstance: Chip8Emulator) {
window.launchQueue?.setConsumer(async (launchParams) => {
if (launchParams.files.length) {
diff --git a/src/styles/style.css b/src/styles/style.css
index f3fcf8a..b5c12e1 100644
--- a/src/styles/style.css
+++ b/src/styles/style.css
@@ -82,16 +82,16 @@ body {
width: 100%;
}
-.rom-controller input {
- content: 'Upload rom file';
- border: 2px solid #34ff66;
- padding: 5px;
- border-radius: 5px;
+#file {
user-select: none;
cursor: pointer;
- flex-grow: 10;
font-family: Verdana;
font-size: 0.83rem;
+ flex-grow: 9;
+ border: 2px solid #34ff66;
+ padding: 5px;
+ border-radius: 5px;
+ text-overflow: ellipsis;
}
.default-button {
@@ -161,26 +161,6 @@ body {
height: 1.9rem;
}
-input[type="file"]::-webkit-file-upload-button {
- display: none;
-}
-
-input[type="file"]::-moz-file-upload-button {
- display: none;
-}
-
-input[type="file"]::-ms-file-upload-button {
- display: none;
-}
-
-input[type="file"]::-o-file-upload-button {
- display: none;
-}
-
-input[type="file"]::file-upload-button {
- display: none;
-}
-
.keyboard-container {
padding: 0.6rem;
}