js-dos 8.1.5 → 8.1.7

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.
Files changed (140) hide show
  1. package/dist/emulators/emulators.js +2 -0
  2. package/dist/emulators/emulators.js.map +1 -0
  3. package/dist/emulators/types/build.d.ts +28 -0
  4. package/dist/emulators/types/dos/bundle/dos-bundle.d.ts +20 -0
  5. package/dist/emulators/types/dos/dosbox/ts/direct.d.ts +3 -0
  6. package/dist/emulators/types/dos/dosbox/ts/worker.d.ts +3 -0
  7. package/dist/emulators/types/emulators.d.ts +76 -0
  8. package/dist/emulators/types/http.d.ts +9 -0
  9. package/dist/emulators/types/impl/ci-impl.d.ts +29 -0
  10. package/dist/emulators/types/impl/emulators-impl.d.ts +26 -0
  11. package/dist/emulators/types/impl/modules.d.ts +38 -0
  12. package/dist/emulators/types/libzip/libzip.d.ts +16 -0
  13. package/dist/emulators/types/protocol/messages-queue.d.ts +8 -0
  14. package/dist/emulators/types/protocol/protocol.d.ts +128 -0
  15. package/dist/emulators/wdosbox-x.js +55 -0
  16. package/dist/emulators/wdosbox-x.js.symbols +8760 -0
  17. package/dist/emulators/wdosbox-x.wasm +0 -0
  18. package/dist/emulators/wdosbox.js +55 -0
  19. package/dist/emulators/wdosbox.js.symbols +3001 -0
  20. package/dist/emulators/wdosbox.wasm +0 -0
  21. package/dist/emulators/wlibzip.js +21 -0
  22. package/dist/emulators/wlibzip.js.symbols +268 -0
  23. package/dist/emulators/wlibzip.wasm +0 -0
  24. package/dist/js-dos.css +1 -0
  25. package/dist/js-dos.js +22 -0
  26. package/dist/js-dos.js.map +1 -0
  27. package/package.json +1 -1
  28. package/release.zip +0 -0
  29. package/.eslintrc.json +0 -43
  30. package/.github/workflows/build.yml +0 -51
  31. package/.gitmodules +0 -4
  32. package/index.html +0 -110
  33. package/postcss.config.cjs +0 -8
  34. package/src/app.css +0 -14
  35. package/src/base.css +0 -10
  36. package/src/components/checkbox.tsx +0 -41
  37. package/src/components/close-button.tsx +0 -17
  38. package/src/components/components.css +0 -28
  39. package/src/components/dos-option-checkbox.tsx +0 -94
  40. package/src/components/dos-option-select.tsx +0 -108
  41. package/src/components/dos-option-slider.tsx +0 -35
  42. package/src/components/error.tsx +0 -16
  43. package/src/components/loading.tsx +0 -26
  44. package/src/components/lock.tsx +0 -10
  45. package/src/components/select.tsx +0 -33
  46. package/src/components/slider.tsx +0 -69
  47. package/src/download-file.ts +0 -18
  48. package/src/frame/account-frame.tsx +0 -156
  49. package/src/frame/editor/defaults.ts +0 -419
  50. package/src/frame/editor/editor-conf-frame.tsx +0 -227
  51. package/src/frame/editor/editor-frame.css +0 -55
  52. package/src/frame/editor/editor-fs-frame.tsx +0 -314
  53. package/src/frame/fat-drives-frame.tsx +0 -199
  54. package/src/frame/frame.css +0 -119
  55. package/src/frame/frame.tsx +0 -34
  56. package/src/frame/image-rendering-frame.tsx +0 -8
  57. package/src/frame/network-frame.tsx +0 -157
  58. package/src/frame/quick-save-frame.tsx +0 -98
  59. package/src/frame/settings-frame.tsx +0 -14
  60. package/src/frame/stats-frame.tsx +0 -87
  61. package/src/host/bundle-storage.ts +0 -91
  62. package/src/host/fullscreen.ts +0 -35
  63. package/src/host/lcache.ts +0 -203
  64. package/src/host/lstorage.ts +0 -156
  65. package/src/i18n.ts +0 -185
  66. package/src/index.css +0 -7
  67. package/src/load.ts +0 -132
  68. package/src/login/login.css +0 -9
  69. package/src/login/login.tsx +0 -77
  70. package/src/main.tsx +0 -197
  71. package/src/public/types.ts +0 -45
  72. package/src/sidebar/account-button.tsx +0 -33
  73. package/src/sidebar/cloud-save-button.tsx +0 -89
  74. package/src/sidebar/diskette-icon.tsx +0 -14
  75. package/src/sidebar/fullscreen-button.tsx +0 -44
  76. package/src/sidebar/network-button.tsx +0 -39
  77. package/src/sidebar/sidebar-button.tsx +0 -244
  78. package/src/sidebar/sidebar.css +0 -47
  79. package/src/sidebar/sidebar.tsx +0 -30
  80. package/src/sockdrive/LICENSE +0 -674
  81. package/src/sockdrive/README.md +0 -45
  82. package/src/sockdrive/include/sockdrive.h +0 -23
  83. package/src/sockdrive/js/.eslintrc.json +0 -43
  84. package/src/sockdrive/js/package.json +0 -29
  85. package/src/sockdrive/js/src/fatfs/chains.js +0 -318
  86. package/src/sockdrive/js/src/fatfs/dir.js +0 -385
  87. package/src/sockdrive/js/src/fatfs/helpers.js +0 -210
  88. package/src/sockdrive/js/src/fatfs/index.js +0 -606
  89. package/src/sockdrive/js/src/fatfs/structs.js +0 -255
  90. package/src/sockdrive/js/src/fatfs/vol.js +0 -166
  91. package/src/sockdrive/js/src/sockdrive/cache.ts +0 -56
  92. package/src/sockdrive/js/src/sockdrive/drive.ts +0 -471
  93. package/src/sockdrive/js/src/sockdrive/lru.ts +0 -221
  94. package/src/sockdrive/js/src/sockdrive/types.ts +0 -14
  95. package/src/sockdrive/js/src/sockdrive-fat.d.ts +0 -64
  96. package/src/sockdrive/js/src/sockdrive-fat.ts +0 -226
  97. package/src/sockdrive/js/src/sockdrive-native.ts +0 -100
  98. package/src/sockdrive/js/src/test/test.ts +0 -289
  99. package/src/sockdrive/js/tsconfig.json +0 -11
  100. package/src/sockdrive/js/webpack.config.js +0 -68
  101. package/src/sockdrive/js/yarn.lock +0 -1808
  102. package/src/store/auth.ts +0 -115
  103. package/src/store/dos.ts +0 -305
  104. package/src/store/editor.ts +0 -61
  105. package/src/store/init.ts +0 -48
  106. package/src/store/storage.ts +0 -32
  107. package/src/store/ui.ts +0 -191
  108. package/src/store.tsx +0 -116
  109. package/src/ui.tsx +0 -140
  110. package/src/v8/changes.ts +0 -56
  111. package/src/v8/config.ts +0 -20
  112. package/src/v8/subscriptions.ts +0 -62
  113. package/src/vite-env.d.ts +0 -5
  114. package/src/window/dos/controls/keyboard.ts +0 -32
  115. package/src/window/dos/controls/keys.ts +0 -331
  116. package/src/window/dos/controls/mouse/mount.ts +0 -99
  117. package/src/window/dos/controls/mouse/mouse-locked.ts +0 -51
  118. package/src/window/dos/controls/mouse/mouse-not-locked.ts +0 -84
  119. package/src/window/dos/controls/mouse/mouse-swipe.ts +0 -57
  120. package/src/window/dos/controls/mouse/pointer.ts +0 -85
  121. package/src/window/dos/controls/mouse.ts +0 -21
  122. package/src/window/dos/dos-dhry2.tsx +0 -191
  123. package/src/window/dos/dos-runtime.tsx +0 -216
  124. package/src/window/dos/dos-window.tsx +0 -91
  125. package/src/window/dos/render/canvas.ts +0 -65
  126. package/src/window/dos/render/resize.ts +0 -31
  127. package/src/window/dos/render/webgl.ts +0 -173
  128. package/src/window/dos/sound/audio-node.ts +0 -148
  129. package/src/window/error-window.tsx +0 -9
  130. package/src/window/loading-window.tsx +0 -54
  131. package/src/window/prerun-window.tsx +0 -121
  132. package/src/window/select-window.tsx +0 -118
  133. package/src/window/window.css +0 -78
  134. package/src/window/window.tsx +0 -49
  135. package/src/ws/ws-sockdrive.ts +0 -123
  136. package/src/ws/ws-transport-layer.ts +0 -468
  137. package/tailwind.config.cjs +0 -48
  138. package/tsconfig.json +0 -32
  139. package/tsconfig.node.json +0 -9
  140. package/vite.config.ts +0 -25
@@ -1,173 +0,0 @@
1
- import { CommandInterface } from "emulators";
2
- import { resizeCanvas } from "./resize";
3
-
4
- const vsSource = `
5
- attribute vec4 aVertexPosition;
6
- attribute vec2 aTextureCoord;
7
-
8
- varying highp vec2 vTextureCoord;
9
-
10
- void main(void) {
11
- gl_Position = aVertexPosition;
12
- vTextureCoord = aTextureCoord;
13
- }
14
- `;
15
-
16
- const fsSource = `
17
- varying highp vec2 vTextureCoord;
18
- uniform sampler2D uSampler;
19
-
20
-
21
- void main(void) {
22
- highp vec4 color = texture2D(uSampler, vTextureCoord);
23
- gl_FragColor = vec4(color.r, color.g, color.b, 1.0);
24
- }
25
- `;
26
-
27
- export function webGl(canvas: HTMLCanvasElement,
28
- ci: CommandInterface,
29
- forceAspect?: number) {
30
- const gl = canvas.getContext("webgl");
31
- if (gl === null) {
32
- throw new Error("Unable to create webgl context on given canvas");
33
- }
34
-
35
- const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
36
- const vertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition");
37
- const textureCoord = gl.getAttribLocation(shaderProgram, "aTextureCoord");
38
- const uSampler = gl.getUniformLocation(shaderProgram, "uSampler");
39
-
40
- initBuffers(gl, vertexPosition, textureCoord);
41
-
42
- const texture = gl.createTexture();
43
- gl.bindTexture(gl.TEXTURE_2D, texture);
44
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
45
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
46
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
47
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
48
-
49
- const pixel = new Uint8Array([0, 0, 0]);
50
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB,
51
- 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE,
52
- pixel);
53
-
54
- gl.useProgram(shaderProgram);
55
- gl.activeTexture(gl.TEXTURE0);
56
- gl.uniform1i(uSampler, 0);
57
-
58
- let frameWidth = 0;
59
- let frameHeight = 0;
60
-
61
- let requestAnimationFrameId: number | null = null;
62
- let frame: Uint8Array | null = null;
63
- let frameFormat: number = 0;
64
-
65
- const updateTexture = () => {
66
- if (frame !== null) {
67
- gl.texImage2D(gl.TEXTURE_2D, 0, frameFormat,
68
- frameWidth, frameHeight, 0, frameFormat, gl.UNSIGNED_BYTE,
69
- frame);
70
- frame = null;
71
- }
72
- gl.drawArrays(gl.TRIANGLES, 0, 6);
73
-
74
- requestAnimationFrameId = null;
75
- };
76
-
77
- const onResize = () => {
78
- resizeCanvas(canvas, frameWidth, frameHeight, forceAspect);
79
- };
80
-
81
- const onResizeFrame = (w: number, h: number) => {
82
- frameWidth = w;
83
- frameHeight = h;
84
- canvas.width = frameWidth;
85
- canvas.height = frameHeight;
86
- frame = null;
87
- gl.viewport(0, 0, frameWidth, frameHeight);
88
- onResize();
89
- };
90
-
91
- ci.events().onFrameSize(onResizeFrame);
92
- ci.events().onFrame((rgb, rgba) => {
93
- frame = rgb != null ? rgb : rgba;
94
- frameFormat = rgb != null ? gl.RGB : gl.RGBA;
95
- if (requestAnimationFrameId === null) {
96
- requestAnimationFrameId = requestAnimationFrame(updateTexture);
97
- }
98
- });
99
-
100
- onResizeFrame(ci.width(), ci.height());
101
-
102
- const resizeObserver = new ResizeObserver(onResize);
103
- resizeObserver.observe(canvas.parentElement!);
104
- window.addEventListener("resize", onResize);
105
-
106
- return () => {
107
- ci.events().onFrameSize(() => {});
108
- ci.events().onFrame(() => {});
109
- resizeObserver.disconnect();
110
- window.removeEventListener("resize", onResize);
111
- };
112
- }
113
-
114
- function initShaderProgram(gl: WebGLRenderingContext, vsSource: string, fsSource: string) {
115
- const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
116
- const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
117
-
118
- const shaderProgram = gl.createProgram() as WebGLShader;
119
- gl.attachShader(shaderProgram, vertexShader);
120
- gl.attachShader(shaderProgram, fragmentShader);
121
- gl.linkProgram(shaderProgram);
122
-
123
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
124
- throw new Error("Unable to initialize the shader program: " + gl.getProgramInfoLog(shaderProgram));
125
- }
126
-
127
- return shaderProgram;
128
- }
129
-
130
- function loadShader(gl: WebGLRenderingContext, shaderType: GLenum, source: string) {
131
- const shader = gl.createShader(shaderType) as WebGLShader;
132
- gl.shaderSource(shader, source);
133
- gl.compileShader(shader);
134
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
135
- const info = gl.getShaderInfoLog(shader);
136
- gl.deleteShader(shader);
137
- throw new Error("An error occurred compiling the shaders: " + info);
138
- }
139
-
140
- return shader;
141
- }
142
-
143
- function initBuffers(gl: WebGLRenderingContext, vertexPosition: number, textureCoord: number) {
144
- const positionBuffer = gl.createBuffer();
145
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
146
- const positions = [
147
- -1.0, -1.0, 0.0,
148
- 1.0, -1.0, 0.0,
149
- 1.0, 1.0, 0.0,
150
- -1.0, -1.0, 0.0,
151
- 1.0, 1.0, 0.0,
152
- -1.0, 1.0, 0.0,
153
- ];
154
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
155
- gl.vertexAttribPointer(vertexPosition, 3, gl.FLOAT, false, 0, 0);
156
- gl.enableVertexAttribArray(vertexPosition);
157
-
158
- const textureCoordBuffer = gl.createBuffer();
159
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
160
- const textureCoordinates = [
161
- 0.0, 1.0,
162
- 1.0, 1.0,
163
- 1.0, 0.0,
164
- 0.0, 1.0,
165
- 1.0, 0.0,
166
- 0.0, 0.0,
167
- ];
168
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
169
- gl.STATIC_DRAW);
170
-
171
- gl.vertexAttribPointer(textureCoord, 2, gl.FLOAT, false, 0, 0);
172
- gl.enableVertexAttribArray(textureCoord);
173
- }
@@ -1,148 +0,0 @@
1
- import { CommandInterface } from "emulators";
2
-
3
- class SamplesQueue {
4
- private samplesQueue: Float32Array[] = [];
5
-
6
- push(samples: Float32Array) {
7
- this.samplesQueue.push(samples);
8
- }
9
-
10
- length() {
11
- let total = 0;
12
- for (const next of this.samplesQueue) {
13
- total += next.length;
14
- }
15
- return total;
16
- }
17
-
18
- writeTo(dst: Float32Array, bufferSize: number) {
19
- let writeIt = 0;
20
- while (this.samplesQueue.length > 0) {
21
- const src = this.samplesQueue[0];
22
- const toRead = Math.min(bufferSize - writeIt, src.length);
23
- if (toRead === src.length) {
24
- dst.set(src, writeIt);
25
- this.samplesQueue.shift();
26
- } else {
27
- dst.set(src.slice(0, toRead), writeIt);
28
- this.samplesQueue[0] = src.slice(toRead);
29
- }
30
-
31
- writeIt += toRead;
32
-
33
- if (writeIt === bufferSize) {
34
- break;
35
- }
36
- }
37
-
38
- if (writeIt < bufferSize) {
39
- dst.fill(0, writeIt);
40
- }
41
- }
42
- }
43
-
44
- export function audioNode(ci: CommandInterface,
45
- bindVolumeFn?: (fn: (volume: number) => void) => () => void) {
46
- const sampleRate = ci.soundFrequency();
47
- const channels = 1;
48
-
49
- if (sampleRate === 0) {
50
- console.warn("Can't create audio node with sampleRate === 0, ingnoring");
51
- return () => {};
52
- }
53
-
54
- let audioContext: AudioContext | null = null;
55
-
56
- if (typeof AudioContext !== "undefined") {
57
- audioContext = new AudioContext({
58
- sampleRate,
59
- latencyHint: "interactive",
60
- });
61
- } else if (typeof (window as any).webkitAudioContext !== "undefined") {
62
- // eslint-disable-next-line new-cap
63
- audioContext = new (window as any).webkitAudioContext({
64
- sampleRate,
65
- latencyHint: "interactive",
66
- });
67
- }
68
-
69
- if (audioContext == null) {
70
- return () => {};
71
- }
72
-
73
- const samplesQueue = new SamplesQueue();
74
- const bufferSize = 2048;
75
- const preBufferSize = 2048;
76
-
77
- ci.events().onSoundPush((samples) => {
78
- if (samplesQueue.length() < bufferSize * 2 + preBufferSize) {
79
- samplesQueue.push(samples);
80
- }
81
- });
82
-
83
- const audioNode = audioContext.createScriptProcessor(bufferSize, 0, channels);
84
- let started = false;
85
-
86
- const onQueueProcess = (event: AudioProcessingEvent) => {
87
- const numFrames = event.outputBuffer.length;
88
- const numChannels = event.outputBuffer.numberOfChannels;
89
- const samplesCount = samplesQueue.length();
90
-
91
- if (!started) {
92
- started = samplesCount >= preBufferSize;
93
- }
94
-
95
- if (!started) {
96
- return;
97
- }
98
-
99
- for (let channel = 0; channel < numChannels; channel++) {
100
- const channelData = event.outputBuffer.getChannelData(channel);
101
- samplesQueue.writeTo(channelData, numFrames);
102
- }
103
- };
104
-
105
- audioNode.onaudioprocess = onQueueProcess;
106
-
107
- const gainNode = audioContext.createGain();
108
- gainNode.connect(audioContext.destination);
109
- audioNode.connect(gainNode);
110
-
111
- gainNode.gain.value = 1.0;
112
-
113
- let unbindVolumeFn: () => void;
114
- if (bindVolumeFn) {
115
- unbindVolumeFn = bindVolumeFn((volume: number) => {
116
- gainNode.gain.value = volume;
117
- });
118
- }
119
-
120
- const resumeWebAudio = () => {
121
- if (audioContext !== null && audioContext.state === "suspended") {
122
- audioContext.resume();
123
- }
124
- };
125
-
126
- document.addEventListener("pointerdown", resumeWebAudio, { once: true });
127
- document.addEventListener("keydown", resumeWebAudio, { once: true });
128
-
129
- return () => {
130
- ci.events().onSoundPush(() => {});
131
-
132
- if (audioContext !== null) {
133
- audioNode.disconnect();
134
- gainNode.disconnect();
135
- audioContext
136
- .close()
137
- .catch(console.error);
138
- audioContext = null;
139
- }
140
-
141
- if (unbindVolumeFn !== undefined) {
142
- unbindVolumeFn();
143
- }
144
-
145
- document.removeEventListener("pointerdown", resumeWebAudio);
146
- document.removeEventListener("keydown", resumeWebAudio);
147
- };
148
- }
@@ -1,9 +0,0 @@
1
- import { useSelector } from "react-redux";
2
- import { Error } from "../components/error";
3
- import { State } from "../store";
4
-
5
- export function ErrorWindow() {
6
- const error = useSelector((state: State) => state.dos.error);
7
- return <Error error={error} />;
8
- }
9
-
@@ -1,54 +0,0 @@
1
- import { useDispatch, useSelector } from "react-redux";
2
- import { formatSize, Loading } from "../components/loading";
3
- import { useT } from "../i18n";
4
- import { State } from "../store";
5
- import { authSlice } from "../store/auth";
6
-
7
- export function LoadingWindow() {
8
- const t = useT();
9
- const step = useSelector((state: State) => state.dos.step);
10
- const received = useSelector((state: State) => state.storage.recived);
11
- const total = useSelector((state: State) => state.storage.total);
12
- const ready = useSelector((state: State) => state.storage.ready);
13
-
14
- let head = t("loading");
15
- let message = "100%";
16
-
17
- switch (step) {
18
- case "bnd-load": {
19
- head = t("bundle_loading");
20
- if (received > 0) {
21
- message = `${formatSize(received)} / ${formatSize(total)}`;
22
-
23
- if (total > 0) {
24
- message += ` (${Math.round(received * 1000 / total) / 10}%)`;
25
- }
26
- }
27
- } break;
28
- case "bnd-config": {
29
- head = t("bundle_config");
30
- }
31
-
32
- default: {
33
- }
34
- }
35
-
36
- return <div class="flex flex-col w-full h-full items-center justify-center">
37
- <Loading head={head} message={message} />
38
- {step === "bnd-load" && ready && <AccountNotReady />}
39
- </div>;
40
- }
41
-
42
- function AccountNotReady() {
43
- const t = useT();
44
- const dispatch = useDispatch();
45
- function skip() {
46
- dispatch(authSlice.actions.ready());
47
- }
48
- return <>
49
- <div class="mt-16 text-2xl">{t("loading_saves")}</div>
50
- <div onClick={skip} class="self-center cursor-pointer underline mt-4 text-lg animate-pulse">
51
- {t("account_not_ready")}
52
- </div>
53
- </>;
54
- }
@@ -1,121 +0,0 @@
1
- import { useDispatch, useSelector } from "react-redux";
2
- import { BackendSelect, RenderAspectSelect, RenderSelect } from "../components/dos-option-select";
3
- import { dosSlice } from "../store/dos";
4
- import { State, useNonSerializableStore } from "../store";
5
- import { HardwareCheckbox, MouseCapture, SockdriveWrite, WorkerCheckbox } from "../components/dos-option-checkbox";
6
- import { MouseSensitiviySlider, VolumeSlider } from "../components/dos-option-slider";
7
- import { useT } from "../i18n";
8
- import { dispatchLoginAction } from "../store/ui";
9
- import { Emulators } from "emulators";
10
-
11
- declare const emulators: Emulators;
12
-
13
- export function PreRunWindow() {
14
- const account = useSelector((state: State) => state.auth.account);
15
- const emuVersion = useSelector((state: State) => state.dos.emuVersion);
16
- const dispatch = useDispatch();
17
- const t = useT();
18
-
19
- function login() {
20
- dispatchLoginAction(account, dispatch);
21
- }
22
-
23
- function openPremiumPage() {
24
- window.open("https://js-dos.com/cloud-overview.html", "_blank");
25
- }
26
-
27
- return <div class="pre-run-window">
28
- <Play class="mb-8" />
29
-
30
- {(account === null) &&
31
- <div class="flex flex-row mb-4 -mt-4 items-center">
32
- <div class="btn btn-accent" onClick={login}>
33
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
34
- <path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25
35
- 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786
36
- 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd" />
37
- </svg>
38
-
39
- {t("please_login")}
40
- </div>
41
- <div class="ml-2 cursor-pointer" onClick={openPremiumPage}>
42
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
43
- stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
44
- <path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025
45
- 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45
46
- 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z" />
47
- </svg>
48
- </div>
49
- </div>
50
- }
51
- {account &&
52
- <div class="flex flex-row mb-4 -mt-4 items-center">
53
- <div class="btn btn-ghost" onClick={login}>
54
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
55
- <path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25
56
- 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786
57
- 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd" />
58
- </svg>
59
-
60
- {account.name ?? account.email}
61
- </div>
62
- </div>
63
- }
64
-
65
- <div class="flex flex-row flex-wrap justify-end">
66
- <div class="flex flex-col items-end">
67
- <BackendSelect />
68
- <RenderSelect />
69
- <SockdriveWrite />
70
- </div>
71
- <div class="ml-10 flex flex-col items-end">
72
- <HardwareCheckbox />
73
- <WorkerCheckbox />
74
- <RenderAspectSelect />
75
- <MouseCapture />
76
- </div>
77
- </div>
78
-
79
- <MouseSensitiviySlider class="mt-4 w-full max-w-sm" />
80
- <VolumeSlider class="w-full max-w-sm" />
81
-
82
- <div class="text-center mt-8">jsdos/emu version:&nbsp;
83
- <span class="text-ellipsis overflow-hidden">{JSDOS_VERSION}/{emuVersion}</span></div>
84
- </div>;
85
- }
86
-
87
- function Play(props: { class?: string }) {
88
- const configChanged = useSelector((state: State) => state.editor.configChanged);
89
- const bundleConfig = useSelector((state: State) => state.editor.bundleConfig);
90
- const nonSerializableStore = useNonSerializableStore();
91
- const dispatch = useDispatch();
92
-
93
- async function onPlay() {
94
- if (configChanged) {
95
- const config = bundleConfig;
96
- const bundle = nonSerializableStore.loadedBundle?.bundle;
97
- if (bundle === null || config === null || !ArrayBuffer.isView(bundle)) {
98
- throw new Error("Unexpected behaviour (internal state is broken), bundle is null");
99
- }
100
-
101
- try {
102
- nonSerializableStore.loadedBundle!.bundle =
103
- await emulators.bundleUpdateConfig(bundle, config);
104
- dispatch(dosSlice.actions.bndPlay({}));
105
- } catch (e) {
106
- dispatch(dosSlice.actions.bndError((e as Error).message ?? "unexpected error"));
107
- }
108
- } else {
109
- dispatch(dosSlice.actions.bndPlay({}));
110
- }
111
- }
112
-
113
- return <div class={props.class + " cursor-pointer"} onClick={onPlay}>
114
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
115
- stroke-width="1.5" stroke="currentColor" class="w-48 h-48 play-button">
116
- <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
117
- <path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 010
118
- .656l-5.603 3.113a.375.375 0 01-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112z" />
119
- </svg>
120
- </div>;
121
- }
@@ -1,118 +0,0 @@
1
- import { useDispatch, useStore } from "react-redux";
2
- import { dosSlice } from "../store/dos";
3
- import { useT } from "../i18n";
4
- import { loadBundleFromFile, loadBundleFromUrl, loadEmptyBundle } from "../load";
5
- import { useState } from "preact/hooks";
6
- import { uiSlice } from "../store/ui";
7
- import { Store } from "../store";
8
-
9
- const fileInput = document.createElement("input");
10
- fileInput.type = "file";
11
-
12
- export function SelectWindow() {
13
- const t = useT();
14
- const store = useStore() as Store;
15
- const [useUrl, setUseUrl] = useState<boolean>(false);
16
-
17
- if (useUrl) {
18
- return <div class="select-window overflow-hidden flex-grow flex flex-col items-center justify-center px-8 py-8">
19
- <Load />
20
- </div>;
21
- }
22
-
23
- async function createEmpty() {
24
- try {
25
- await loadEmptyBundle(store).catch(console.error);
26
- } catch (e: any) {
27
- store.dispatch(dosSlice.actions.bndError(e.message ?? "unexpected error"));
28
- }
29
- }
30
-
31
- return <div class="select-window overflow-hidden flex-grow flex flex-col items-center justify-center px-8">
32
- <div class="mb-4 text-center underline cursor-pointer hover:text-accent"
33
- onClick={() => setUseUrl(true)}>{t("load_by_url")}</div>
34
- <Upload />
35
- <div class="mt-4 text-center">{t("upload_file")}</div>
36
- <div class="mt-4 text-center underline cursor-pointer hover:text-accent"
37
- onClick={createEmpty}>{t("create_empty")}</div>
38
- </div>;
39
- }
40
-
41
- function Load() {
42
- const t = useT();
43
- const store = useStore();
44
- const dispatch = useDispatch();
45
- const [url, setUrl] = useState<string>("");
46
- const [error, setError] = useState<string | null>(null);
47
-
48
- async function loadBundle(url: string) {
49
- dispatch(uiSlice.actions.frameNone());
50
-
51
- let validUrl;
52
- try {
53
- validUrl = new URL(url);
54
- } catch (e: any) {
55
- setError(e.message);
56
- return;
57
- }
58
-
59
- try {
60
- await loadBundleFromUrl(validUrl.toString(), store);
61
- } catch (e: any) {
62
- dispatch(dosSlice.actions.bndError(e.message ?? "unexpected error"));
63
- }
64
- }
65
-
66
- return <>
67
- <div class="form-control w-3/4 mb-4">
68
- <label class="label">
69
- <span class="label-text">{t("enter_url")}:</span>
70
- </label>
71
- <input type="text"
72
- class="input w-full input-sm input-bordered"
73
- onChange={(e) => setUrl(e.currentTarget.value ?? "")}
74
- value={url}></input>
75
- </div>
76
- <div class="mt-4 text-center underline cursor-pointer hover:text-accent"
77
- onClick={() => loadBundle(url)}>{t("load")}</div>
78
- {error !== null &&
79
- <div class="mt-8 text-center text-error">
80
- {error}
81
- </div>
82
- }
83
- </>;
84
- }
85
-
86
- function Upload() {
87
- const store = useStore() as Store;
88
-
89
- async function onFileChange() {
90
- fileInput.removeEventListener("change", onFileChange);
91
-
92
- if (fileInput.files === null || fileInput.files.length === 0) {
93
- return;
94
- }
95
-
96
- const file = fileInput.files[0];
97
- try {
98
- await loadBundleFromFile(file, store).catch((e) => store.dispatch(dosSlice.actions.bndError(e.message)));
99
- } catch (e: any) {
100
- store.dispatch(dosSlice.actions.bndError(e.message ?? "unexpected error"));
101
- }
102
- }
103
-
104
- function onUpload() {
105
- fileInput.addEventListener("change", onFileChange);
106
- fileInput.click();
107
- }
108
-
109
- return <div class="cursor-pointer" onClick={onUpload}>
110
- <svg xmlns="http://www.w3.org/2000/svg" fill="none"
111
- viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-48 h-48 play-button">
112
- <path stroke-linecap="round" stroke-linejoin="round" d="M9 13.5l3 3m0 0l3-3m-3
113
- 3v-6m1.06-4.19l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25
114
- 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5
115
- 1.5 0 01-1.06-.44z" />
116
- </svg>
117
- </div>;
118
- }