From 803b58ca0df2bea9c16f7ebaf49088be8e8b27d1 Mon Sep 17 00:00:00 2001 From: Alexander Guryanov Date: Wed, 8 Nov 2023 13:35:20 +0600 Subject: [PATCH] support dosboxConf --- src/frame/editor/defaults.ts | 5 +++-- src/frame/editor/editor-conf-frame.tsx | 1 - src/load.ts | 20 +++++++++++++++++--- src/main.tsx | 18 ++++++++++++++---- src/non-serializable-store.ts | 4 ++-- src/public/types.ts | 5 +++-- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/frame/editor/defaults.ts b/src/frame/editor/defaults.ts index cb1573ae..4dd9807d 100644 --- a/src/frame/editor/defaults.ts +++ b/src/frame/editor/defaults.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ export const dosboxconf = [{ name: "DOS", backend: "dosbox", @@ -207,7 +208,7 @@ echo on # █ ███ █ ▀█▀▀▄▀▀▄████▀▀█▄█ # █ ▀▀▀ █ ▄▀▀█▀█▀▄ ▀▀▄▄█▄█ # ▀▀▀▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀▀▀ -`.replace(/\n/g, "\r\n") +`.replace(/\n/g, "\r\n"), }, { name: "X - DOS 7.1", backend: "dosboxX", @@ -339,5 +340,5 @@ echo on # ▀▀▀▀▀▀▀ ▀ ▀▀ ▀ ▀ ▀▀▀ # `.replace(/\n/g, "\r\n"), -} +}, ]; diff --git a/src/frame/editor/editor-conf-frame.tsx b/src/frame/editor/editor-conf-frame.tsx index 26255fc7..0daaa1ec 100644 --- a/src/frame/editor/editor-conf-frame.tsx +++ b/src/frame/editor/editor-conf-frame.tsx @@ -4,7 +4,6 @@ import { State } from "../../store"; import { editorSlice } from "../../store/editor"; import { dosboxconf } from "./defaults"; import { dosSlice } from "../../store/dos"; -import { uiSlice } from "../../store/ui"; export function EditorConf() { const t = useT(); diff --git a/src/load.ts b/src/load.ts index 8c567916..914ff252 100644 --- a/src/load.ts +++ b/src/load.ts @@ -1,5 +1,5 @@ import { Dispatch, Unsubscribe } from "@reduxjs/toolkit"; -import { Emulators } from "emulators"; +import { DosConfig, Emulators } from "emulators"; import { dosSlice } from "./store/dos"; import { nonSerializableStore } from "./non-serializable-store"; import { bundleFromChanges, bundleFromFile, bundleFromUrl } from "./host/bundle-storage"; @@ -36,6 +36,20 @@ export function loadBundleFromFile(file: File, dispatch: Dispatch) { null, null, dispatch); } +export async function loadBundleFromConfg(config: DosConfig, dispatch: Dispatch) { + nonSerializableStore.loadedBundle = null; + + dispatch(editorSlice.actions.init(config)); + dispatch(dosSlice.actions.mouseCapture(config.dosboxConf.indexOf("autolock=true") > 0)); + + nonSerializableStore.loadedBundle = { + bundleUrl: null, + bundleChangesUrl: null, + bundle: config, + bundleChanges: null, + }; + dispatch(dosSlice.actions.bndReady({})); +} export async function loadBundleFromUrl(url: string, dispatch: Dispatch) { const owner = store.getState().auth.account?.email ?? "guest"; @@ -108,10 +122,10 @@ async function changesProducer(bundleUrl: string): Promise<{ export async function updateBundleConf() { const config = store.getState().editor.bundleConfig; const bundle = nonSerializableStore.loadedBundle?.bundle; - if (bundle === null || config === null) { + if (bundle === null || config === null || !ArrayBuffer.isView(bundle)) { throw new Error("Unexpected behaviour (internal state is broken), bundle is null"); } nonSerializableStore.loadedBundle!.bundle = - await emulators.bundleUpdateConfig(bundle!, config); + await emulators.bundleUpdateConfig(bundle, config); } diff --git a/src/main.tsx b/src/main.tsx index 0b5ea6aa..b0ca156a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -11,7 +11,7 @@ import { uiSlice } from "./store/ui"; import { i18nSlice } from "./i18n"; import { nonSerializableStore, postJsDosEvent } from "./non-serializable-store"; import { getCache } from "./host/lcache"; -import { loadBundleFromUrl } from "./load"; +import { loadBundleFromConfg, loadBundleFromUrl } from "./load"; import { DosOptions, DosProps, DosFn } from "./public/types"; import { browserSetFullScreen } from "./host/fullscreen"; @@ -33,8 +33,18 @@ async function pollEvents() { nonSerializableStore.cache = await getCache(cachedEmail ?? "guest"); if (nonSerializableStore.options.url) { - loadBundleFromUrl(nonSerializableStore.options.url, store.dispatch) - .catch((e) => store.dispatch(dosSlice.actions.bndError(e.message))); + try { + await loadBundleFromUrl(nonSerializableStore.options.url, store.dispatch); + } catch (e: any) { + store.dispatch(dosSlice.actions.bndError(e.message)); + } + } else if (nonSerializableStore.options.dosboxConf) { + loadBundleFromConfg({ + dosboxConf: nonSerializableStore.options.dosboxConf, + jsdosConf: { + version: "8", + }, + }, store.dispatch); } else { store.dispatch(uiSlice.actions.windowSelect()); } @@ -49,7 +59,7 @@ store.subscribe(pollEvents); let skipEmulatorsInit = false; export const Dos: DosFn = (element: HTMLDivElement, - options: Partial = {}): DosProps =>{ + options: Partial = {}): DosProps => { nonSerializableStore.options = options; setupRootElement(element); diff --git a/src/non-serializable-store.ts b/src/non-serializable-store.ts index 8ab9002e..84a4b4a9 100644 --- a/src/non-serializable-store.ts +++ b/src/non-serializable-store.ts @@ -1,4 +1,4 @@ -import { CommandInterface } from "emulators"; +import { CommandInterface, InitFs } from "emulators"; import { Cache, CacheNoop } from "./host/lcache"; import { Dispatch } from "@reduxjs/toolkit"; import { DosOptions } from "./public/types"; @@ -6,7 +6,7 @@ import { DosOptions } from "./public/types"; export interface LoadedBundle { bundleUrl: string | null, bundleChangesUrl: string | null, - bundle: Uint8Array | null, + bundle: InitFs | null, bundleChanges: Uint8Array | null, } diff --git a/src/public/types.ts b/src/public/types.ts index c66b0fea..949c4b80 100644 --- a/src/public/types.ts +++ b/src/public/types.ts @@ -1,6 +1,7 @@ export interface DosOptions { - url: string | null, - background: string | null, + url: string, + dosboxConf: string, + background: string, pathPrefix: string, theme: "light" | "dark" | "cupcake" | "bumblebee" | "emerald" | "corporate" | "synthwave" | "retro" | "cyberpunk" | "valentine" | "halloween" | "garden" |