js-dos 7.4.9 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build.yml +51 -0
- package/.gitmodules +4 -0
- package/README.deployment.md +11 -0
- package/README.md +29 -89
- package/index.html +106 -0
- package/package.json +46 -71
- package/postcss.config.cjs +8 -0
- package/src/app.css +14 -0
- package/src/base.css +10 -0
- package/src/components/checkbox.tsx +41 -0
- package/src/components/close-button.tsx +17 -0
- package/src/components/components.css +28 -0
- package/src/components/dos-option-checkbox.tsx +94 -0
- package/src/components/dos-option-select.tsx +108 -0
- package/src/components/dos-option-slider.tsx +35 -0
- package/src/components/error.tsx +16 -0
- package/src/components/loading.tsx +26 -0
- package/src/components/lock.tsx +10 -0
- package/src/components/select.tsx +33 -0
- package/src/components/slider.tsx +69 -0
- package/src/download-file.ts +18 -0
- package/src/frame/account-frame.tsx +156 -0
- package/src/frame/editor/defaults.ts +419 -0
- package/src/frame/editor/editor-conf-frame.tsx +226 -0
- package/src/frame/editor/editor-frame.css +55 -0
- package/src/frame/editor/editor-fs-frame.tsx +314 -0
- package/src/frame/fat-drives-frame.tsx +135 -0
- package/src/frame/frame.css +119 -0
- package/src/frame/frame.tsx +34 -0
- package/src/frame/image-rendering-frame.tsx +8 -0
- package/src/frame/network-frame.tsx +157 -0
- package/src/frame/quick-save-frame.tsx +96 -0
- package/src/frame/settings-frame.tsx +14 -0
- package/src/frame/stats-frame.tsx +87 -0
- package/src/host/bundle-storage.ts +91 -0
- package/src/host/fullscreen.ts +35 -0
- package/src/host/lcache.ts +203 -0
- package/src/host/lstorage.ts +156 -0
- package/src/i18n.ts +179 -0
- package/src/index.css +7 -0
- package/src/load.ts +132 -0
- package/src/login/login.css +9 -0
- package/src/login/login.tsx +77 -0
- package/src/main.tsx +197 -0
- package/src/public/types.ts +41 -0
- package/src/sidebar/account-button.tsx +33 -0
- package/src/sidebar/cloud-save-button.tsx +89 -0
- package/src/sidebar/diskette-icon.tsx +14 -0
- package/src/sidebar/fullscreen-button.tsx +44 -0
- package/src/sidebar/network-button.tsx +39 -0
- package/src/sidebar/sidebar-button.tsx +244 -0
- package/src/sidebar/sidebar.css +47 -0
- package/src/sidebar/sidebar.tsx +30 -0
- package/src/sockdrive/LICENSE +674 -0
- package/src/sockdrive/README.md +45 -0
- package/src/sockdrive/include/sockdrive.h +23 -0
- package/src/sockdrive/js/.eslintrc.json +43 -0
- package/src/sockdrive/js/package.json +29 -0
- package/src/sockdrive/js/src/fatfs/chains.js +318 -0
- package/src/sockdrive/js/src/fatfs/dir.js +385 -0
- package/src/sockdrive/js/src/fatfs/helpers.js +210 -0
- package/src/sockdrive/js/src/fatfs/index.js +606 -0
- package/src/sockdrive/js/src/fatfs/structs.js +255 -0
- package/src/sockdrive/js/src/fatfs/vol.js +166 -0
- package/src/sockdrive/js/src/sockdrive/cache.ts +133 -0
- package/src/sockdrive/js/src/sockdrive/drive.ts +457 -0
- package/src/sockdrive/js/src/sockdrive/lru.ts +221 -0
- package/src/sockdrive/js/src/sockdrive/types.ts +14 -0
- package/src/sockdrive/js/src/sockdrive-fat.d.ts +64 -0
- package/src/sockdrive/js/src/sockdrive-fat.ts +226 -0
- package/src/sockdrive/js/src/sockdrive-native.ts +100 -0
- package/src/sockdrive/js/src/test/test.ts +288 -0
- package/src/sockdrive/js/tsconfig.json +11 -0
- package/src/sockdrive/js/webpack.config.js +68 -0
- package/src/sockdrive/js/yarn.lock +1808 -0
- package/src/store/auth.ts +115 -0
- package/src/store/dos.ts +305 -0
- package/src/store/editor.ts +61 -0
- package/src/store/init.ts +48 -0
- package/src/store/storage.ts +32 -0
- package/src/store/ui.ts +186 -0
- package/src/store.tsx +108 -0
- package/src/ui.tsx +104 -0
- package/src/v8/changes.ts +56 -0
- package/src/v8/config.ts +18 -0
- package/src/v8/subscriptions.ts +62 -0
- package/src/vite-env.d.ts +2 -0
- package/src/window/dos/controls/keyboard.ts +32 -0
- package/src/window/dos/controls/keys.ts +331 -0
- package/src/window/dos/controls/mouse/mount.ts +99 -0
- package/src/window/dos/controls/mouse/mouse-locked.ts +51 -0
- package/src/window/dos/controls/mouse/mouse-not-locked.ts +84 -0
- package/src/window/dos/controls/mouse/mouse-swipe.ts +57 -0
- package/src/window/dos/controls/mouse/pointer.ts +85 -0
- package/src/window/dos/controls/mouse.ts +21 -0
- package/src/window/dos/dos-dhry2.tsx +191 -0
- package/src/window/dos/dos-runtime.tsx +214 -0
- package/src/window/dos/dos-window.tsx +84 -0
- package/src/window/dos/render/canvas.ts +65 -0
- package/src/window/dos/render/resize.ts +31 -0
- package/src/window/dos/render/webgl.ts +173 -0
- package/src/window/dos/sound/audio-node.ts +148 -0
- package/src/window/error-window.tsx +9 -0
- package/src/window/loading-window.tsx +54 -0
- package/src/window/prerun-window.tsx +123 -0
- package/src/window/select-window.tsx +118 -0
- package/src/window/window.css +78 -0
- package/src/window/window.tsx +49 -0
- package/src/ws/ws-sockdrive.ts +101 -0
- package/src/ws/ws-transport-layer.ts +455 -0
- package/tailwind.config.cjs +48 -0
- package/tsconfig.json +32 -0
- package/tsconfig.node.json +9 -0
- package/vite.config.ts +22 -0
- package/LICENSE +0 -339
- package/dist/emulators-ui-loader.png +0 -0
- package/dist/js-dos.css +0 -1690
- package/dist/js-dos.js +0 -17
- package/dist/js-dos.js.map +0 -1
- package/dist/types/src/backend/v7/latency.d.ts +0 -8
- package/dist/types/src/backend/v7/personal.d.ts +0 -2
- package/dist/types/src/backend/v7/v7-config.d.ts +0 -16
- package/dist/types/src/components/action-bar.d.ts +0 -2
- package/dist/types/src/components/action-hide.d.ts +0 -4
- package/dist/types/src/components/action-save-or-exit.d.ts +0 -4
- package/dist/types/src/components/client.d.ts +0 -6
- package/dist/types/src/components/controls.d.ts +0 -8
- package/dist/types/src/components/cpu-control.d.ts +0 -2
- package/dist/types/src/components/horizontal-slider.d.ts +0 -13
- package/dist/types/src/components/region.d.ts +0 -6
- package/dist/types/src/components/scale-control.d.ts +0 -3
- package/dist/types/src/components/sensitivity-control.d.ts +0 -3
- package/dist/types/src/components/sidebar/latency-info.d.ts +0 -7
- package/dist/types/src/components/sidebar/main.d.ts +0 -2
- package/dist/types/src/components/sidebar/networking.d.ts +0 -2
- package/dist/types/src/components/sidebar/token/token-add-time.d.ts +0 -2
- package/dist/types/src/components/sidebar/token/token-select.d.ts +0 -2
- package/dist/types/src/components/sidebar/token/token.d.ts +0 -17
- package/dist/types/src/components/sidebar.d.ts +0 -2
- package/dist/types/src/components/sync-control.d.ts +0 -2
- package/dist/types/src/components/tip.d.ts +0 -2
- package/dist/types/src/components/vertical-slider.d.ts +0 -12
- package/dist/types/src/components/volume-control.d.ts +0 -3
- package/dist/types/src/dom.d.ts +0 -8
- package/dist/types/src/hardware-transport-layer.d.ts +0 -18
- package/dist/types/src/icons.d.ts +0 -95
- package/dist/types/src/player-app.d.ts +0 -50
- package/dist/types/src/player.d.ts +0 -29
- package/dist/types/src/request.d.ts +0 -1
- package/dist/types/src/xhr.d.ts +0 -6
- package/dist/types/v7-services/src/personal.d.ts +0 -3
- package/dist/wdosbox.js +0 -55
- package/dist/wdosbox.js.symbols +0 -3174
- package/dist/wdosbox.wasm +0 -0
- package/examples/digger/index.html +0 -71
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
+
import { getCache } from "../host/lcache";
|
|
3
|
+
import { lStorage } from "../host/lstorage";
|
|
4
|
+
import { DosAction, getNonSerializableStore } from "../store";
|
|
5
|
+
import { dosSlice } from "./dos";
|
|
6
|
+
|
|
7
|
+
const cachedAccount = "cached.account";
|
|
8
|
+
|
|
9
|
+
export interface Token {
|
|
10
|
+
access_token: string,
|
|
11
|
+
refresh_token: string,
|
|
12
|
+
scope: string,
|
|
13
|
+
expires_in: number,
|
|
14
|
+
validUntilMs: number;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export interface Account {
|
|
18
|
+
email: string,
|
|
19
|
+
name: null | string,
|
|
20
|
+
picture: null | string,
|
|
21
|
+
token: Token,
|
|
22
|
+
premium: boolean,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const initAccount = (() => {
|
|
26
|
+
const params = new URLSearchParams(location.search);
|
|
27
|
+
const refreshToken = params.get("jsdos_token");
|
|
28
|
+
if (refreshToken !== null) {
|
|
29
|
+
setRefreshToken(refreshToken);
|
|
30
|
+
history.replaceState(null, "", location.href.substring(0, location.href.indexOf("?")));
|
|
31
|
+
return null;
|
|
32
|
+
} else {
|
|
33
|
+
const json = lStorage.getItem(cachedAccount);
|
|
34
|
+
const account = json !== null ? JSON.parse(json) : null;
|
|
35
|
+
return account !== null && account.token.validUntilMs - Date.now() > 1 * 60 * 60 * 1000 ?
|
|
36
|
+
account : null;
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
39
|
+
|
|
40
|
+
const initialState: {
|
|
41
|
+
account: Account | null,
|
|
42
|
+
ready: boolean,
|
|
43
|
+
} = {
|
|
44
|
+
account: initAccount,
|
|
45
|
+
ready: initAccount !== null,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type AuthState = typeof initialState;
|
|
49
|
+
|
|
50
|
+
export const authSlice = createSlice({
|
|
51
|
+
name: "auth",
|
|
52
|
+
initialState,
|
|
53
|
+
reducers: {
|
|
54
|
+
login: (state, action: { payload: Account }) => {
|
|
55
|
+
setRefreshToken(action.payload.token.refresh_token);
|
|
56
|
+
state.account = action.payload;
|
|
57
|
+
state.account.premium = state.account.premium ||
|
|
58
|
+
state.account.email === "dz.caiiiycuk@gmail.com" ||
|
|
59
|
+
state.account.email === "caiiiycuk@gmail.com";
|
|
60
|
+
lStorage.setItem(cachedAccount, JSON.stringify(action.payload));
|
|
61
|
+
(action as unknown as DosAction).asyncStore((store) => {
|
|
62
|
+
if (action.payload.email === "dz.caiiiycuk@gmail.com" ||
|
|
63
|
+
action.payload.email === "caiiiycuk@gmail.com") {
|
|
64
|
+
store.dispatch(dosSlice.actions.setSockdriveWrite(false));
|
|
65
|
+
}
|
|
66
|
+
getCache(action.payload.email)
|
|
67
|
+
.then((cache) => getNonSerializableStore(store).cache = cache)
|
|
68
|
+
.catch(console.error)
|
|
69
|
+
.finally(() => {
|
|
70
|
+
store.dispatch(authSlice.actions.ready());
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
logout: (state, action) => {
|
|
75
|
+
clearRefreshToken();
|
|
76
|
+
lStorage.removeItem(cachedAccount);
|
|
77
|
+
(action as unknown as DosAction).asyncStore((store) => {
|
|
78
|
+
getCache("guest")
|
|
79
|
+
.then((cache) => getNonSerializableStore(store).cache = cache)
|
|
80
|
+
.catch(console.error);
|
|
81
|
+
});
|
|
82
|
+
state.account = null;
|
|
83
|
+
},
|
|
84
|
+
ready: (state) => {
|
|
85
|
+
state.ready = true;
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export function postAuthMessage(action: "auth/login" | "auth/authenicate") {
|
|
91
|
+
const message = {
|
|
92
|
+
action,
|
|
93
|
+
refresh_token: action === "auth/authenicate" ? getRefreshToken() : undefined,
|
|
94
|
+
url: action === "auth/login" ? location.href : undefined,
|
|
95
|
+
};
|
|
96
|
+
document.querySelector<HTMLIFrameElement>("#authentificator")!
|
|
97
|
+
.contentWindow?.postMessage(message, "*");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getRefreshToken(): string | null {
|
|
101
|
+
return lStorage.getItem("cached.rt");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function setRefreshToken(refreshToken: string | null) {
|
|
105
|
+
if (refreshToken === null) {
|
|
106
|
+
clearRefreshToken();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return lStorage.setItem("cached.rt", refreshToken);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function clearRefreshToken() {
|
|
114
|
+
lStorage.removeItem("cached.rt");
|
|
115
|
+
}
|
package/src/store/dos.ts
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
+
import { DosAction, getNonSerializableStore, makeStore, postJsDosEvent } from "../store";
|
|
3
|
+
import { Emulators } from "emulators";
|
|
4
|
+
import { lStorage } from "../host/lstorage";
|
|
5
|
+
|
|
6
|
+
const alphabet = "qwertyuiopasdfghjklzxcvbnm1234567890";
|
|
7
|
+
declare const emulators: Emulators;
|
|
8
|
+
export interface BundleConfig {
|
|
9
|
+
name?: string,
|
|
10
|
+
version?: string,
|
|
11
|
+
backend?: string,
|
|
12
|
+
render?: string,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const BackendValues = <const>["dosbox", "dosboxX"];
|
|
16
|
+
export type Backend = typeof BackendValues[number];
|
|
17
|
+
|
|
18
|
+
export const RenderBackendValues = <const>["webgl", "canvas"];
|
|
19
|
+
export type RenderBackend = typeof RenderBackendValues[number];
|
|
20
|
+
|
|
21
|
+
export const RenderAspectValues = <const>["AsIs", "1/1", "5/4", "4/3", "16/10", "16/9", "Fit"];
|
|
22
|
+
export type RenderAspect = typeof RenderAspectValues[number];
|
|
23
|
+
export const FitConstant = 65535;
|
|
24
|
+
|
|
25
|
+
export const ImageRenderingValues = <const>["pixelated", "smooth"];
|
|
26
|
+
export type ImageRendering = typeof ImageRenderingValues[number];
|
|
27
|
+
|
|
28
|
+
export interface EmulatorStats {
|
|
29
|
+
cyclesPerMs: number,
|
|
30
|
+
nonSkippableSleepPreSec: number,
|
|
31
|
+
sleepPerSec: number,
|
|
32
|
+
sleepTimePerSec: number,
|
|
33
|
+
framePerSec: number,
|
|
34
|
+
soundPerSec: number,
|
|
35
|
+
msgSentPerSec: number,
|
|
36
|
+
msgRecvPerSec: number,
|
|
37
|
+
netSent: number,
|
|
38
|
+
netRecv: number,
|
|
39
|
+
driveSent: number,
|
|
40
|
+
driveRecv: number,
|
|
41
|
+
driveRecvTime: number,
|
|
42
|
+
driveCacheHit: number,
|
|
43
|
+
driveCacheMiss: number,
|
|
44
|
+
driveCacheUsed: number,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const initialState: {
|
|
48
|
+
step:
|
|
49
|
+
"emu-init" | "emu-error" | "emu-ready" |
|
|
50
|
+
"bnd-load" | "bnd-error" | "bnd-config" | "bnd-ready" |
|
|
51
|
+
"bnd-play",
|
|
52
|
+
emuVersion: string,
|
|
53
|
+
worker: boolean,
|
|
54
|
+
backend: Backend,
|
|
55
|
+
backendLocked: boolean,
|
|
56
|
+
backendHardware: boolean,
|
|
57
|
+
renderBackend: RenderBackend,
|
|
58
|
+
renderAspect: RenderAspect,
|
|
59
|
+
volume: number,
|
|
60
|
+
mouseSensitivity: number,
|
|
61
|
+
mouseCapture: boolean,
|
|
62
|
+
paused: boolean,
|
|
63
|
+
error: null | undefined | string,
|
|
64
|
+
bundle: string | null,
|
|
65
|
+
config: BundleConfig,
|
|
66
|
+
stats: EmulatorStats,
|
|
67
|
+
ci: boolean,
|
|
68
|
+
ciStartedAt: number,
|
|
69
|
+
network: {
|
|
70
|
+
server: "netherlands" | "newyork" | "singapore",
|
|
71
|
+
room: string,
|
|
72
|
+
ipx: "connecting" | "connected" | "disconnected" | "error",
|
|
73
|
+
},
|
|
74
|
+
imageRendering: ImageRendering,
|
|
75
|
+
sockdriveWrite: boolean,
|
|
76
|
+
} = {
|
|
77
|
+
step: "emu-init",
|
|
78
|
+
emuVersion: "-",
|
|
79
|
+
error: null,
|
|
80
|
+
bundle: null,
|
|
81
|
+
config: {},
|
|
82
|
+
worker: lStorage.getItem("worker") !== "false",
|
|
83
|
+
backend: (lStorage.getItem("backend") ?? "dosbox") as Backend,
|
|
84
|
+
backendLocked: false,
|
|
85
|
+
backendHardware: (lStorage.getItem("backendHardware") !== "false"),
|
|
86
|
+
renderBackend: (lStorage.getItem("renderBackend") ?? "webgl") as RenderBackend,
|
|
87
|
+
renderAspect: (lStorage.getItem("renderAspect") ?? "AsIs") as RenderAspect,
|
|
88
|
+
volume: (Number.parseFloat(lStorage.getItem("volume") ?? "1.0")),
|
|
89
|
+
mouseSensitivity: (Number.parseFloat(lStorage.getItem("mouse_sensitivity") ?? "1.0")),
|
|
90
|
+
mouseCapture: false,
|
|
91
|
+
paused: false,
|
|
92
|
+
stats: {
|
|
93
|
+
cyclesPerMs: 0,
|
|
94
|
+
nonSkippableSleepPreSec: 0,
|
|
95
|
+
sleepPerSec: 0,
|
|
96
|
+
sleepTimePerSec: 0,
|
|
97
|
+
framePerSec: 0,
|
|
98
|
+
soundPerSec: 0,
|
|
99
|
+
msgSentPerSec: 0,
|
|
100
|
+
msgRecvPerSec: 0,
|
|
101
|
+
netRecv: 0,
|
|
102
|
+
netSent: 0,
|
|
103
|
+
driveSent: 0,
|
|
104
|
+
driveRecv: 0,
|
|
105
|
+
driveRecvTime: 0,
|
|
106
|
+
driveCacheHit: 0,
|
|
107
|
+
driveCacheMiss: 0,
|
|
108
|
+
driveCacheUsed: 0,
|
|
109
|
+
},
|
|
110
|
+
network: {
|
|
111
|
+
server: (lStorage.getItem("net.server") ?? "netherlands") as any,
|
|
112
|
+
room: randomRoom(),
|
|
113
|
+
ipx: "disconnected",
|
|
114
|
+
},
|
|
115
|
+
ci: false,
|
|
116
|
+
ciStartedAt: 0,
|
|
117
|
+
imageRendering: (lStorage.getItem("imageRendering") ?? "pixelated") as any,
|
|
118
|
+
sockdriveWrite: true,
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export type DosState = typeof initialState;
|
|
122
|
+
|
|
123
|
+
export const dosSlice = createSlice({
|
|
124
|
+
name: "dos",
|
|
125
|
+
initialState,
|
|
126
|
+
reducers: {
|
|
127
|
+
emuReady: (s, a: { payload: string }) => {
|
|
128
|
+
s.step = "emu-ready";
|
|
129
|
+
s.emuVersion = a.payload;
|
|
130
|
+
},
|
|
131
|
+
emuError: (s, a: { payload: string }) => {
|
|
132
|
+
s.step = "emu-error";
|
|
133
|
+
s.error = a.payload ?? "Unexpeceted error";
|
|
134
|
+
},
|
|
135
|
+
bndLoad: (s, a: { payload: string }) => {
|
|
136
|
+
s.step = "bnd-load";
|
|
137
|
+
s.bundle = a.payload;
|
|
138
|
+
},
|
|
139
|
+
bndError: (s, a: { payload: string }) => {
|
|
140
|
+
s.step = "bnd-error";
|
|
141
|
+
s.error = a.payload ?? "Unexpeceted error";
|
|
142
|
+
},
|
|
143
|
+
bndConfig: (s) => {
|
|
144
|
+
s.step = "bnd-config";
|
|
145
|
+
},
|
|
146
|
+
bndReady: (s, a: { payload: BundleConfig }) => {
|
|
147
|
+
s.step = "bnd-ready";
|
|
148
|
+
s.config = a.payload;
|
|
149
|
+
},
|
|
150
|
+
bndPlay: (s, a) => {
|
|
151
|
+
s.step = "bnd-play";
|
|
152
|
+
(a as unknown as DosAction).asyncStore((store) => {
|
|
153
|
+
postJsDosEvent(getNonSerializableStore(store), "bnd-play");
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
dosWorker: (s, a: { payload: boolean }) => {
|
|
157
|
+
s.worker = a.payload;
|
|
158
|
+
lStorage.setItem("worker", s.worker ? "true" : "false");
|
|
159
|
+
},
|
|
160
|
+
dosBackend: (s, a: { payload: Backend }) => {
|
|
161
|
+
s.backend = a.payload as Backend;
|
|
162
|
+
},
|
|
163
|
+
dosBackendLocked: (s, a: { payload: boolean }) => {
|
|
164
|
+
s.backendLocked = a.payload;
|
|
165
|
+
},
|
|
166
|
+
dosBackendHardware: (s, a: { payload: boolean }) => {
|
|
167
|
+
s.backendHardware = a.payload;
|
|
168
|
+
lStorage.setItem("backendHardware", s.backendHardware ? "true" : "false");
|
|
169
|
+
},
|
|
170
|
+
renderBackend: (s, a: { payload: RenderBackend }) => {
|
|
171
|
+
s.renderBackend = a.payload;
|
|
172
|
+
lStorage.setItem("renderBackend", s.renderBackend);
|
|
173
|
+
},
|
|
174
|
+
renderAspect: (s, a: { payload: RenderAspect }) => {
|
|
175
|
+
s.renderAspect = a.payload;
|
|
176
|
+
lStorage.setItem("renderAspect", s.renderAspect);
|
|
177
|
+
},
|
|
178
|
+
imageRendering: (s, a: { payload: ImageRendering }) => {
|
|
179
|
+
s.imageRendering = a.payload;
|
|
180
|
+
lStorage.setItem("imageRendering", s.imageRendering);
|
|
181
|
+
},
|
|
182
|
+
volume: (s, a: { payload: number }) => {
|
|
183
|
+
s.volume = a.payload;
|
|
184
|
+
lStorage.setItem("volume", s.volume + "");
|
|
185
|
+
},
|
|
186
|
+
mouseSensitivity: (s, a: { payload: number }) => {
|
|
187
|
+
s.mouseSensitivity = a.payload;
|
|
188
|
+
lStorage.setItem("mouse_sensitivity", s.mouseSensitivity + "");
|
|
189
|
+
},
|
|
190
|
+
mouseCapture: (s, a: { payload: boolean }) => {
|
|
191
|
+
s.mouseCapture = a.payload;
|
|
192
|
+
},
|
|
193
|
+
paused: (s, a: { payload: boolean }) => {
|
|
194
|
+
s.paused = a.payload;
|
|
195
|
+
},
|
|
196
|
+
stats: (s, a: { payload: EmulatorStats }) => {
|
|
197
|
+
s.stats = a.payload;
|
|
198
|
+
},
|
|
199
|
+
ci: (s, a: { payload: boolean }) => {
|
|
200
|
+
s.ci = a.payload;
|
|
201
|
+
if (a.payload) {
|
|
202
|
+
s.ciStartedAt = Date.now();
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
connectIpx: (s, a: { payload: { room: string, address: string } }) => {
|
|
206
|
+
if (s.network.ipx === "connected") {
|
|
207
|
+
throw new Error("Already connected");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!s.ci) {
|
|
211
|
+
throw new Error("DOS is not started");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const { room, address } = a.payload;
|
|
215
|
+
s.network.ipx = "connecting";
|
|
216
|
+
(a as unknown as DosAction).asyncStore((store) => {
|
|
217
|
+
const nonSerializableStore = getNonSerializableStore(store);
|
|
218
|
+
if (!nonSerializableStore.ci) {
|
|
219
|
+
throw new Error("DOS is not started");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const canonicalAddress = address.endsWith("/") ?
|
|
223
|
+
address.substring(0, address.length - 1) :
|
|
224
|
+
address;
|
|
225
|
+
|
|
226
|
+
nonSerializableStore.ci.networkConnect(0 /* NetworkType.NETWORK_DOSBOX_IPX */,
|
|
227
|
+
canonicalAddress + ":1900/ipx/" + room.replaceAll("@", "_"))
|
|
228
|
+
.then(() => {
|
|
229
|
+
store.dispatch(dosSlice.actions.statusIpx("connected"));
|
|
230
|
+
})
|
|
231
|
+
.catch((e) => {
|
|
232
|
+
store.dispatch(dosSlice.actions.statusIpx("error"));
|
|
233
|
+
console.error(e);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
statusIpx: (s, a: { payload: "error" | "connected" | "connecting" }) => {
|
|
238
|
+
s.network.ipx = a.payload;
|
|
239
|
+
},
|
|
240
|
+
disconnectIpx: (s, a) => {
|
|
241
|
+
s.network.ipx = "disconnected";
|
|
242
|
+
(a as unknown as DosAction).asyncStore((store) => {
|
|
243
|
+
getNonSerializableStore(store).ci?.networkDisconnect(0 /* IPX */);
|
|
244
|
+
});
|
|
245
|
+
},
|
|
246
|
+
setRoom: (s, a: { payload: string }) => {
|
|
247
|
+
s.network.room = a.payload;
|
|
248
|
+
},
|
|
249
|
+
setServer: (s, a: { payload: typeof initialState.network.server }) => {
|
|
250
|
+
s.network.server = a.payload;
|
|
251
|
+
lStorage.setItem("net.server", a.payload);
|
|
252
|
+
},
|
|
253
|
+
setSockdriveWrite: (s, a: { payload: boolean }) => {
|
|
254
|
+
s.sockdriveWrite = a.payload;
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
let emulatorsReady = false;
|
|
260
|
+
export function initEmulators(store: ReturnType<typeof makeStore>, pathPrefix: string) {
|
|
261
|
+
store.dispatch(async (dispatch) => {
|
|
262
|
+
try {
|
|
263
|
+
if (!emulatorsReady) {
|
|
264
|
+
await initEmulatorsJs(pathPrefix);
|
|
265
|
+
emulatorsReady = true;
|
|
266
|
+
}
|
|
267
|
+
dispatch(dosSlice.actions.emuReady(emulators.version));
|
|
268
|
+
} catch (e) {
|
|
269
|
+
console.error("Unable to init emulators.js", e);
|
|
270
|
+
dispatch(dosSlice.actions.emuError((e as any).message));
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function initEmulatorsJs(pathPrefix: string) {
|
|
276
|
+
const el = document.querySelector("#emulators.js");
|
|
277
|
+
if (el !== null) {
|
|
278
|
+
return Promise.resolve();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return new Promise<void>((resolve, reject) => {
|
|
282
|
+
const script = document.createElement("script");
|
|
283
|
+
script.async = true;
|
|
284
|
+
script.type = "text/javascript";
|
|
285
|
+
script.src = pathPrefix + "emulators.js";
|
|
286
|
+
script.onload = () => {
|
|
287
|
+
emulators.pathPrefix = pathPrefix;
|
|
288
|
+
resolve();
|
|
289
|
+
};
|
|
290
|
+
script.onerror = (err) => {
|
|
291
|
+
reject(new Error("Unable to add emulators.js. Probably you should set the " +
|
|
292
|
+
"'pathPrefix' option to point to the js-dos folder."));
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
document.head.appendChild(script);
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
function randomSymbol() {
|
|
300
|
+
return alphabet[Math.round(Math.random() * (alphabet.length - 1))];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function randomRoom() {
|
|
304
|
+
return randomSymbol() + randomSymbol() + randomSymbol();
|
|
305
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
+
import { DosConfig } from "emulators";
|
|
3
|
+
import { Node } from "react-checkbox-tree";
|
|
4
|
+
import { dosboxconf } from "../frame/editor/defaults";
|
|
5
|
+
|
|
6
|
+
const initialState: {
|
|
7
|
+
// step: "empty" | "extract" | "ready" | "error",
|
|
8
|
+
configChanged: boolean,
|
|
9
|
+
bundleConfig: DosConfig | null,
|
|
10
|
+
errorMessage: string | null,
|
|
11
|
+
fs: Node[],
|
|
12
|
+
} = {
|
|
13
|
+
// step: "empty",
|
|
14
|
+
configChanged: false,
|
|
15
|
+
bundleConfig: null,
|
|
16
|
+
errorMessage: null,
|
|
17
|
+
fs: [],
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type EditorState = typeof initialState;
|
|
21
|
+
|
|
22
|
+
export const editorSlice = createSlice({
|
|
23
|
+
name: "editor",
|
|
24
|
+
initialState,
|
|
25
|
+
reducers: {
|
|
26
|
+
init: (s, a: { payload: DosConfig | null }) => {
|
|
27
|
+
if (a.payload === null) {
|
|
28
|
+
s.configChanged = true;
|
|
29
|
+
s.bundleConfig = {
|
|
30
|
+
dosboxConf: dosboxconf[0].contents,
|
|
31
|
+
jsdosConf: {
|
|
32
|
+
version: "js-dos-v8",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
} else {
|
|
36
|
+
s.configChanged = false;
|
|
37
|
+
s.bundleConfig = a.payload;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
dosboxConf: (s, a: { payload: string }) => {
|
|
41
|
+
s.configChanged = true;
|
|
42
|
+
s.bundleConfig!.dosboxConf = a.payload;
|
|
43
|
+
},
|
|
44
|
+
// empty: (s) => {
|
|
45
|
+
// s.step = "empty";
|
|
46
|
+
// },
|
|
47
|
+
// extract: (s) => {
|
|
48
|
+
// s.step = "extract";
|
|
49
|
+
// },
|
|
50
|
+
// ready: (s) => {
|
|
51
|
+
// s.step = "ready";
|
|
52
|
+
// },
|
|
53
|
+
// config: (s, a: { payload: DosConfig | null }) => {
|
|
54
|
+
// s.bundleConfig = a.payload;
|
|
55
|
+
// },
|
|
56
|
+
// error: (s, a: { payload: string }) => {
|
|
57
|
+
// s.step = "error";
|
|
58
|
+
// s.errorMessage = a.payload;
|
|
59
|
+
// },
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
+
import { lStorage } from "../host/lstorage";
|
|
3
|
+
|
|
4
|
+
export const sockdriveBackendNames = ["localhost", "js-dos"];
|
|
5
|
+
export type SockdriveBackendName = typeof sockdriveBackendNames[number];
|
|
6
|
+
export const sockdriveBackend: {
|
|
7
|
+
[key: SockdriveBackendName]: {
|
|
8
|
+
sockdriveEndpoint: string,
|
|
9
|
+
sockdriveWssEndpoint: string,
|
|
10
|
+
}
|
|
11
|
+
} = {
|
|
12
|
+
"js-dos": {
|
|
13
|
+
sockdriveEndpoint: "https://backend.make-vm.com:8001",
|
|
14
|
+
sockdriveWssEndpoint: "wss://backend.make-vm.com:8001",
|
|
15
|
+
},
|
|
16
|
+
"localhost": {
|
|
17
|
+
sockdriveEndpoint: "http://localhost:8001",
|
|
18
|
+
sockdriveWssEndpoint: "ws://localhost:8001",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface InitState {
|
|
23
|
+
uid: string,
|
|
24
|
+
sockdriveBackendName: SockdriveBackendName,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
let storeUid = -1;
|
|
28
|
+
export function createInitSlice() {
|
|
29
|
+
storeUid += 1;
|
|
30
|
+
return {
|
|
31
|
+
storeUid,
|
|
32
|
+
slice: createSlice({
|
|
33
|
+
name: "init",
|
|
34
|
+
initialState: {
|
|
35
|
+
uid: storeUid,
|
|
36
|
+
sockdriveBackendName: lStorage.getItem("sockdrive.backend.name") ?? "js-dos",
|
|
37
|
+
},
|
|
38
|
+
reducers: {
|
|
39
|
+
setSockdriveBackendName: (state, a: { payload: SockdriveBackendName }) => {
|
|
40
|
+
state.sockdriveBackendName = a.payload;
|
|
41
|
+
lStorage.setItem("sockdrive.backend.name", a.payload);
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const initSlice = createInitSlice().slice;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
+
|
|
3
|
+
const initialState: {
|
|
4
|
+
recived: number,
|
|
5
|
+
total: number,
|
|
6
|
+
ready: boolean,
|
|
7
|
+
} = {
|
|
8
|
+
recived: 0,
|
|
9
|
+
total: 0,
|
|
10
|
+
ready: false,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type StorageState = typeof initialState;
|
|
14
|
+
|
|
15
|
+
export const storageSlice = createSlice({
|
|
16
|
+
name: "storage",
|
|
17
|
+
initialState,
|
|
18
|
+
reducers: {
|
|
19
|
+
reset: (s) => {
|
|
20
|
+
s.recived = -1;
|
|
21
|
+
s.total = 0;
|
|
22
|
+
s.ready = false;
|
|
23
|
+
},
|
|
24
|
+
progress: (s, a: { payload: [number, number ] }) => {
|
|
25
|
+
s.recived = a.payload[0];
|
|
26
|
+
s.total = a.payload[1];
|
|
27
|
+
},
|
|
28
|
+
ready: (s) => {
|
|
29
|
+
s.ready = true;
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|