js-dos 8.1.4 → 8.1.6

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 (141) hide show
  1. package/README.md +1 -1
  2. package/dist/emulators/emulators.js +2 -0
  3. package/dist/emulators/emulators.js.map +1 -0
  4. package/dist/emulators/types/build.d.ts +28 -0
  5. package/dist/emulators/types/dos/bundle/dos-bundle.d.ts +20 -0
  6. package/dist/emulators/types/dos/dosbox/ts/direct.d.ts +3 -0
  7. package/dist/emulators/types/dos/dosbox/ts/worker.d.ts +3 -0
  8. package/dist/emulators/types/emulators.d.ts +76 -0
  9. package/dist/emulators/types/http.d.ts +9 -0
  10. package/dist/emulators/types/impl/ci-impl.d.ts +29 -0
  11. package/dist/emulators/types/impl/emulators-impl.d.ts +26 -0
  12. package/dist/emulators/types/impl/modules.d.ts +38 -0
  13. package/dist/emulators/types/libzip/libzip.d.ts +16 -0
  14. package/dist/emulators/types/protocol/messages-queue.d.ts +8 -0
  15. package/dist/emulators/types/protocol/protocol.d.ts +128 -0
  16. package/dist/emulators/wdosbox-x.js +55 -0
  17. package/dist/emulators/wdosbox-x.js.symbols +8760 -0
  18. package/dist/emulators/wdosbox-x.wasm +0 -0
  19. package/dist/emulators/wdosbox.js +55 -0
  20. package/dist/emulators/wdosbox.js.symbols +3001 -0
  21. package/dist/emulators/wdosbox.wasm +0 -0
  22. package/dist/emulators/wlibzip.js +21 -0
  23. package/dist/emulators/wlibzip.js.symbols +268 -0
  24. package/dist/emulators/wlibzip.wasm +0 -0
  25. package/dist/js-dos.css +1 -0
  26. package/dist/js-dos.js +22 -0
  27. package/dist/js-dos.js.map +1 -0
  28. package/package.json +1 -1
  29. package/release.zip +0 -0
  30. package/.eslintrc.json +0 -43
  31. package/.github/workflows/build.yml +0 -51
  32. package/.gitmodules +0 -4
  33. package/index.html +0 -110
  34. package/postcss.config.cjs +0 -8
  35. package/src/app.css +0 -14
  36. package/src/base.css +0 -10
  37. package/src/components/checkbox.tsx +0 -41
  38. package/src/components/close-button.tsx +0 -17
  39. package/src/components/components.css +0 -28
  40. package/src/components/dos-option-checkbox.tsx +0 -94
  41. package/src/components/dos-option-select.tsx +0 -108
  42. package/src/components/dos-option-slider.tsx +0 -35
  43. package/src/components/error.tsx +0 -16
  44. package/src/components/loading.tsx +0 -26
  45. package/src/components/lock.tsx +0 -10
  46. package/src/components/select.tsx +0 -33
  47. package/src/components/slider.tsx +0 -69
  48. package/src/download-file.ts +0 -18
  49. package/src/frame/account-frame.tsx +0 -156
  50. package/src/frame/editor/defaults.ts +0 -419
  51. package/src/frame/editor/editor-conf-frame.tsx +0 -227
  52. package/src/frame/editor/editor-frame.css +0 -55
  53. package/src/frame/editor/editor-fs-frame.tsx +0 -314
  54. package/src/frame/fat-drives-frame.tsx +0 -199
  55. package/src/frame/frame.css +0 -119
  56. package/src/frame/frame.tsx +0 -34
  57. package/src/frame/image-rendering-frame.tsx +0 -8
  58. package/src/frame/network-frame.tsx +0 -157
  59. package/src/frame/quick-save-frame.tsx +0 -98
  60. package/src/frame/settings-frame.tsx +0 -14
  61. package/src/frame/stats-frame.tsx +0 -87
  62. package/src/host/bundle-storage.ts +0 -91
  63. package/src/host/fullscreen.ts +0 -35
  64. package/src/host/lcache.ts +0 -203
  65. package/src/host/lstorage.ts +0 -156
  66. package/src/i18n.ts +0 -185
  67. package/src/index.css +0 -7
  68. package/src/load.ts +0 -132
  69. package/src/login/login.css +0 -9
  70. package/src/login/login.tsx +0 -77
  71. package/src/main.tsx +0 -197
  72. package/src/public/types.ts +0 -45
  73. package/src/sidebar/account-button.tsx +0 -33
  74. package/src/sidebar/cloud-save-button.tsx +0 -89
  75. package/src/sidebar/diskette-icon.tsx +0 -14
  76. package/src/sidebar/fullscreen-button.tsx +0 -44
  77. package/src/sidebar/network-button.tsx +0 -39
  78. package/src/sidebar/sidebar-button.tsx +0 -244
  79. package/src/sidebar/sidebar.css +0 -47
  80. package/src/sidebar/sidebar.tsx +0 -30
  81. package/src/sockdrive/LICENSE +0 -674
  82. package/src/sockdrive/README.md +0 -45
  83. package/src/sockdrive/include/sockdrive.h +0 -23
  84. package/src/sockdrive/js/.eslintrc.json +0 -43
  85. package/src/sockdrive/js/package.json +0 -29
  86. package/src/sockdrive/js/src/fatfs/chains.js +0 -318
  87. package/src/sockdrive/js/src/fatfs/dir.js +0 -385
  88. package/src/sockdrive/js/src/fatfs/helpers.js +0 -210
  89. package/src/sockdrive/js/src/fatfs/index.js +0 -606
  90. package/src/sockdrive/js/src/fatfs/structs.js +0 -255
  91. package/src/sockdrive/js/src/fatfs/vol.js +0 -166
  92. package/src/sockdrive/js/src/sockdrive/cache.ts +0 -56
  93. package/src/sockdrive/js/src/sockdrive/drive.ts +0 -471
  94. package/src/sockdrive/js/src/sockdrive/lru.ts +0 -221
  95. package/src/sockdrive/js/src/sockdrive/types.ts +0 -14
  96. package/src/sockdrive/js/src/sockdrive-fat.d.ts +0 -64
  97. package/src/sockdrive/js/src/sockdrive-fat.ts +0 -226
  98. package/src/sockdrive/js/src/sockdrive-native.ts +0 -100
  99. package/src/sockdrive/js/src/test/test.ts +0 -289
  100. package/src/sockdrive/js/tsconfig.json +0 -11
  101. package/src/sockdrive/js/webpack.config.js +0 -68
  102. package/src/sockdrive/js/yarn.lock +0 -1808
  103. package/src/store/auth.ts +0 -115
  104. package/src/store/dos.ts +0 -305
  105. package/src/store/editor.ts +0 -61
  106. package/src/store/init.ts +0 -48
  107. package/src/store/storage.ts +0 -32
  108. package/src/store/ui.ts +0 -191
  109. package/src/store.tsx +0 -116
  110. package/src/ui.tsx +0 -140
  111. package/src/v8/changes.ts +0 -56
  112. package/src/v8/config.ts +0 -20
  113. package/src/v8/subscriptions.ts +0 -62
  114. package/src/vite-env.d.ts +0 -5
  115. package/src/window/dos/controls/keyboard.ts +0 -32
  116. package/src/window/dos/controls/keys.ts +0 -331
  117. package/src/window/dos/controls/mouse/mount.ts +0 -99
  118. package/src/window/dos/controls/mouse/mouse-locked.ts +0 -51
  119. package/src/window/dos/controls/mouse/mouse-not-locked.ts +0 -84
  120. package/src/window/dos/controls/mouse/mouse-swipe.ts +0 -57
  121. package/src/window/dos/controls/mouse/pointer.ts +0 -85
  122. package/src/window/dos/controls/mouse.ts +0 -21
  123. package/src/window/dos/dos-dhry2.tsx +0 -191
  124. package/src/window/dos/dos-runtime.tsx +0 -216
  125. package/src/window/dos/dos-window.tsx +0 -91
  126. package/src/window/dos/render/canvas.ts +0 -65
  127. package/src/window/dos/render/resize.ts +0 -31
  128. package/src/window/dos/render/webgl.ts +0 -173
  129. package/src/window/dos/sound/audio-node.ts +0 -148
  130. package/src/window/error-window.tsx +0 -9
  131. package/src/window/loading-window.tsx +0 -54
  132. package/src/window/prerun-window.tsx +0 -121
  133. package/src/window/select-window.tsx +0 -118
  134. package/src/window/window.css +0 -78
  135. package/src/window/window.tsx +0 -49
  136. package/src/ws/ws-sockdrive.ts +0 -123
  137. package/src/ws/ws-transport-layer.ts +0 -468
  138. package/tailwind.config.cjs +0 -48
  139. package/tsconfig.json +0 -32
  140. package/tsconfig.node.json +0 -9
  141. 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
- }