From 6451aebe6e339d568551de204f1e8d5d72a22208 Mon Sep 17 00:00:00 2001 From: Sergiotarxz Date: Fri, 24 Mar 2023 03:22:21 +0100 Subject: [PATCH] Refactoring a little the mess of everything in page.tsx --- js-src/components/close-button.tsx | 12 ++++++ js-src/components/overlay-controls.tsx | 28 +++++++++++++ js-src/components/overlay-menu.tsx | 48 ++++++++++++++++++++++ js-src/components/page.tsx | 57 ++++++++++---------------- js-src/constants.ts | 10 ++--- public/js/bundle.js | 34 ++++++++++++++- 6 files changed, 146 insertions(+), 43 deletions(-) create mode 100644 js-src/components/close-button.tsx create mode 100644 js-src/components/overlay-controls.tsx create mode 100644 js-src/components/overlay-menu.tsx diff --git a/js-src/components/close-button.tsx b/js-src/components/close-button.tsx new file mode 100644 index 0000000..e0d932d --- /dev/null +++ b/js-src/components/close-button.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; + +import {CLOSE_BUTTON_IMAGE} from '/constants'; + +export interface CloseButtonProps { + onClick: () => void; +}; +export default function CloseButton({onClick}: CloseButtonProps) { + return ( + Close button, a common 'x' + ); +} diff --git a/js-src/components/overlay-controls.tsx b/js-src/components/overlay-controls.tsx new file mode 100644 index 0000000..7411785 --- /dev/null +++ b/js-src/components/overlay-controls.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import {HOME_BUTTON_IMAGE} from '/constants'; + +export interface OverlayControlsProps { + firstMenuElement: React.RefObject, + setHiddenMenu: (c: boolean) => void, +}; + +export default function OverlayControls({firstMenuElement, setHiddenMenu}: OverlayControlsProps) { + function showOverlayMenu() { + if (firstMenuElement.current == null) { + return; + } + firstMenuElement.current.focus(); + setHiddenMenu(false); + } + return ( +
+
+
+
+ + Go to menu. (House icon) + +
+
+ ); +} diff --git a/js-src/components/overlay-menu.tsx b/js-src/components/overlay-menu.tsx new file mode 100644 index 0000000..17bdb99 --- /dev/null +++ b/js-src/components/overlay-menu.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import CloseButton from '/components/close-button'; +import {CLOSE_BUTTON_IMAGE} from '/constants'; + +export interface OverlayMenuProps { + hiddenMenu: boolean, + setHiddenMenu: (c: boolean) => void, + emulationStarted: boolean, + setHiddenFormSelectFiles: (c: boolean) => void, +}; + +interface Style { + [id: string]: string; +}; + +export default function OverlayMenu({hiddenMenu, setHiddenMenu, emulationStarted, setHiddenFormSelectFiles}: OverlayMenuProps) { + function exitMenu() { + setHiddenMenu(true); + } + + function openSelectFilesMenu() { + setHiddenFormSelectFiles(false); + } + + const styleSelectRom: Style = {}; + if (emulationStarted) { + styleSelectRom.display = 'none'; + } + + const styleMenu: Style = {}; + if (hiddenMenu) { + styleMenu.display = 'none'; + } + + return ( +
+
+ +
+
+ +
+
+ ); +} diff --git a/js-src/components/page.tsx b/js-src/components/page.tsx index c61e6b5..7761f56 100644 --- a/js-src/components/page.tsx +++ b/js-src/components/page.tsx @@ -3,6 +3,9 @@ import * as React from 'react'; import CenterElement from '/components/center-element'; import FormSelectFiles from '/components/form-select-files'; import CanvasGBAEmulator from '/components/canvas-gba-emulator'; +import OverlayControls from '/components/overlay-controls'; +import OverlayMenu from '/components/overlay-menu'; +import CloseButton from '/components/close-button'; import Endian from '/endian'; @@ -14,13 +17,17 @@ export interface handleClickStartEmulationButtonObjectArgs { e: React.MouseEvent; inputRom: HTMLInputElement | null; inputSaveState: HTMLInputElement | null; - setHiddenFormSelectFiles: (c: setBooleanCallback) => void; canvas: HTMLCanvasElement | null; printingFrame: boolean; setPrintingFrame: (c: setBooleanCallback) => void; + setEmulationStarted: (c: boolean) => void, + setHiddenMenu: (c: boolean) => void; + setHiddenFormSelectFiles: (c: boolean) => void; }; -function handleClickStartEmulationButton({e, inputRom, inputSaveState, setHiddenFormSelectFiles, canvas, printingFrame, setPrintingFrame}: handleClickStartEmulationButtonObjectArgs) { +function handleClickStartEmulationButton({e, inputRom, inputSaveState, canvas, printingFrame, + setPrintingFrame, setEmulationStarted, setHiddenMenu, + setHiddenFormSelectFiles}: handleClickStartEmulationButtonObjectArgs) { e.preventDefault(); if (canvas == null) { alert('Canvas does not exists?'); @@ -47,18 +54,20 @@ function handleClickStartEmulationButton({e, inputRom, inputSaveState, setHidden const savestate_file = inputSaveState.files[0]; rom_file.arrayBuffer().then((rom_buffer) => { savestate_file.arrayBuffer().then((savestate_buffer) => { - setHiddenFormSelectFiles((c: boolean) => true); const rom_array = new Uint8Array(rom_buffer); const savestate_array = new Uint8Array(savestate_buffer); const websocket = new WebSocket(`ws://${window.location.host}/ws`); websocket.binaryType = 'arraybuffer'; websocket.onclose = (message) => { - setHiddenFormSelectFiles(c => false); + setEmulationStarted(false); console.log('Closing websocket.'); } websocket.onopen = () => { console.log('Opened websocket.'); + setEmulationStarted(true); sendHello(websocket, rom_array, savestate_array); + setHiddenMenu(true); + setHiddenFormSelectFiles(true); }; setPrintingFrame(c => false); websocket.addEventListener('message', (event) => { @@ -170,59 +179,35 @@ export default function Page() { React.useEffect(resizeCanvas, [emulatorDimensions]); const refInputRom = React.useRef(null); const refInputSaveState = React.useRef(null); + const [emulationStarted, setEmulationStarted] = React.useState(false); + const [hiddenMenu, setHiddenMenu] = React.useState(true); const onStartEmulation = (e: React.MouseEvent) => { handleClickStartEmulationButton({ e: e, - setHiddenFormSelectFiles: setHiddenFormSelectFiles, + setEmulationStarted: setEmulationStarted, inputRom: refInputRom.current, inputSaveState: refInputSaveState.current, canvas: canvasRef.current, setPrintingFrame: setPrintingFrame, printingFrame: printingFrame, + setHiddenMenu: setHiddenMenu, + setHiddenFormSelectFiles: setHiddenFormSelectFiles, }); }; - const [hiddenMenu, setHiddenMenu] = React.useState(true); - const [emulationStarted, setEmulationStarted] = React.useState(false); let firstMenuElement = React.useRef(null); return (
- - + +
- ) => setHiddenFormSelectFiles(true)} href="#">Close button, a common 'x' + setHiddenFormSelectFiles(true)}/>
) => { - setHiddenFormSelectFiles(true); - setHiddenMenu(true); - setEmulationStarted(true); onStartEmulation(e) }}/> diff --git a/js-src/constants.ts b/js-src/constants.ts index 1736c0f..c835e8a 100644 --- a/js-src/constants.ts +++ b/js-src/constants.ts @@ -2,14 +2,14 @@ export const MIN_WIDTH = 240; export const MIN_HEIGHT = 160; export const PACKET_ID_HELLO = 0n; export const PACKET_ID_SEND_FRAME = 1n; +export const CLOSE_BUTTON_IMAGE: string = "/img/close.png"; +export const HOME_BUTTON_IMAGE: string = "/img/home.png"; + export default class Constants { public static MIN_WIDTH: number = MIN_WIDTH; public static MIN_HEIGHT: number = MIN_HEIGHT; public static PACKET_ID_HELLO: bigint = PACKET_ID_HELLO; public static PACKET_ID_SEND_FRAME: bigint = PACKET_ID_SEND_FRAME; - + public static CLOSE_BUTTON_IMAGE: string = CLOSE_BUTTON_IMAGE; + public static HOME_BUTTON_IMAGE: string = HOME_BUTTON_IMAGE; }; -Constants.MIN_WIDTH = MIN_WIDTH; -Constants.MIN_HEIGHT = MIN_HEIGHT; -Constants.PACKET_ID_HELLO = PACKET_ID_HELLO; -Constants.PACKET_ID_SEND_FRAME = PACKET_ID_SEND_FRAME; diff --git a/public/js/bundle.js b/public/js/bundle.js index d96345d..6daceb6 100644 --- a/public/js/bundle.js +++ b/public/js/bundle.js @@ -100,6 +100,16 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./js-src/components/close-button.tsx": +/*!********************************************!*\ + !*** ./js-src/components/close-button.tsx ***! + \********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ CloseButton)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n\n\n;\nfunction CloseButton({ onClick }) {\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { onClick: onClick, href: \"#\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: _constants__WEBPACK_IMPORTED_MODULE_1__.CLOSE_BUTTON_IMAGE, alt: \"Close button, a common 'x'\" })));\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/close-button.tsx?"); + +/***/ }), + /***/ "./js-src/components/form-select-files.tsx": /*!*************************************************!*\ !*** ./js-src/components/form-select-files.tsx ***! @@ -110,13 +120,33 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ }), +/***/ "./js-src/components/overlay-controls.tsx": +/*!************************************************!*\ + !*** ./js-src/components/overlay-controls.tsx ***! + \************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OverlayControls)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n\n\n;\nfunction OverlayControls({ firstMenuElement, setHiddenMenu }) {\n function showOverlayMenu() {\n if (firstMenuElement.current == null) {\n return;\n }\n firstMenuElement.current.focus();\n setHiddenMenu(false);\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"vertical-padding\" }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"controls\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { ref: firstMenuElement, className: \"gear control\", onClick: showOverlayMenu },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: _constants__WEBPACK_IMPORTED_MODULE_1__.HOME_BUTTON_IMAGE, alt: \"Go to menu. (House icon)\" })))));\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/overlay-controls.tsx?"); + +/***/ }), + +/***/ "./js-src/components/overlay-menu.tsx": +/*!********************************************!*\ + !*** ./js-src/components/overlay-menu.tsx ***! + \********************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ OverlayMenu)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _components_close_button__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../components/close-button */ \"./js-src/components/close-button.tsx\");\n\n\n;\n;\nfunction OverlayMenu({ hiddenMenu, setHiddenMenu, emulationStarted, setHiddenFormSelectFiles }) {\n function exitMenu() {\n setHiddenMenu(true);\n }\n function openSelectFilesMenu() {\n setHiddenFormSelectFiles(false);\n }\n const styleSelectRom = {};\n if (emulationStarted) {\n styleSelectRom.display = 'none';\n }\n const styleMenu = {};\n if (hiddenMenu) {\n styleMenu.display = 'none';\n }\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { style: styleMenu, className: \"overlay-menu-div\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu-div-header\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_close_button__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { onClick: exitMenu })),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"ul\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { style: styleSelectRom, onClick: openSelectFilesMenu, href: \"#\" }, \"Select rom\")),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { href: \"#\", onClick: exitMenu }, \"Exit\"))))));\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/overlay-menu.tsx?"); + +/***/ }), + /***/ "./js-src/components/page.tsx": /*!************************************!*\ !*** ./js-src/components/page.tsx ***! \************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Page)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _components_center_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../components/center-element */ \"./js-src/components/center-element.tsx\");\n/* harmony import */ var _components_form_select_files__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../components/form-select-files */ \"./js-src/components/form-select-files.tsx\");\n/* harmony import */ var _components_canvas_gba_emulator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../components/canvas-gba-emulator */ \"./js-src/components/canvas-gba-emulator.tsx\");\n/* harmony import */ var _endian__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../endian */ \"./js-src/endian.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n\n\n\n\n\n\n;\nfunction handleClickStartEmulationButton({ e, inputRom, inputSaveState, setHiddenFormSelectFiles, canvas, printingFrame, setPrintingFrame }) {\n e.preventDefault();\n if (canvas == null) {\n alert('Canvas does not exists?');\n return;\n }\n const ctx = canvas.getContext('2d');\n if (ctx == null) {\n alert('Unable to create canvas context, doing nothing');\n return;\n }\n if (inputRom == null || inputSaveState == null || inputRom.files == null || inputSaveState.files == null) {\n alert('Unable to read the files ');\n return;\n }\n if (inputRom.files.length == 0) {\n alert('There is no rom still');\n return;\n }\n if (inputSaveState.files.length == 0) {\n alert('There is no savestate still');\n return;\n }\n const rom_file = inputRom.files[0];\n const savestate_file = inputSaveState.files[0];\n rom_file.arrayBuffer().then((rom_buffer) => {\n savestate_file.arrayBuffer().then((savestate_buffer) => {\n setHiddenFormSelectFiles((c) => true);\n const rom_array = new Uint8Array(rom_buffer);\n const savestate_array = new Uint8Array(savestate_buffer);\n const websocket = new WebSocket(`ws://${window.location.host}/ws`);\n websocket.binaryType = 'arraybuffer';\n websocket.onclose = (message) => {\n setHiddenFormSelectFiles(c => false);\n console.log('Closing websocket.');\n };\n websocket.onopen = () => {\n console.log('Opened websocket.');\n sendHello(websocket, rom_array, savestate_array);\n };\n setPrintingFrame(c => false);\n websocket.addEventListener('message', (event) => {\n onWebSocketPacket(event, canvas, ctx, printingFrame, setPrintingFrame);\n });\n });\n });\n}\nfunction concatU8Array(array1, array2) {\n const final_array = new Uint8Array(array1.length + array2.length);\n final_array.set(array1);\n final_array.set(array2, array1.length);\n return final_array;\n}\nfunction sendPacket(websocket, id, raw_data) {\n const packet_u8 = concatU8Array(concatU8Array(_endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].u64ToByteArrayBigEndian(id), _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].u64ToByteArrayBigEndian(BigInt(raw_data.length))), raw_data);\n const packet_buffer = packet_u8.buffer;\n console.log('Sending packet');\n websocket.send(packet_buffer);\n}\nfunction sendHello(websocket, rom_array, savestate_array) {\n console.log('Sending hello.');\n const length_rom = BigInt(rom_array.length);\n const length_savestate = BigInt(savestate_array.length);\n const raw_data = concatU8Array(concatU8Array(concatU8Array(_endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].u64ToByteArrayBigEndian(length_rom), rom_array), _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].u64ToByteArrayBigEndian(length_savestate)), savestate_array);\n sendPacket(websocket, _constants__WEBPACK_IMPORTED_MODULE_5__.PACKET_ID_HELLO, raw_data);\n}\nfunction onWebSocketPacket(event, canvas, ctx, printingFrame, setPrintingFrame) {\n const buffer = event.data;\n let packet_u8 = new Uint8Array(buffer);\n const id = _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].byteArrayToU64BigEndian(packet_u8.slice(0, 8));\n packet_u8 = packet_u8.slice(8, packet_u8.length);\n const size = _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].byteArrayToU64BigEndian(packet_u8.slice(0, 8));\n const raw_data = packet_u8.slice(8, packet_u8.length);\n packet_u8 = null;\n switch (id) {\n case _constants__WEBPACK_IMPORTED_MODULE_5__.PACKET_ID_SEND_FRAME:\n handleSendFrame(raw_data, canvas, ctx, printingFrame, setPrintingFrame);\n break;\n default:\n console.log(`Received unknown packet ${id}`);\n }\n}\nfunction handleSendFrame(raw_data, canvas, ctx, printingFrame, setPrintingFrame) {\n if (printingFrame) {\n return;\n }\n setPrintingFrame(c => true);\n let data = raw_data;\n const stride = _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].byteArrayToU32BigEndian(data.slice(0, 4));\n data = data.slice(4, data.length);\n const output_buffer_size = _endian__WEBPACK_IMPORTED_MODULE_4__[\"default\"].byteArrayToU64BigEndian(data.slice(0, 8));\n data = data.slice(8, data.length);\n const img_data = ctx.createImageData(_constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH, _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT);\n const img_data_u8 = new Uint8Array(img_data.data.buffer);\n for (let i = 0; i < data.length; i++) {\n if (i % 4 == 3) {\n img_data_u8[i] = 255;\n continue;\n }\n img_data_u8[i] = data[i];\n }\n data = null;\n createImageBitmap(img_data).then((bitmap) => drawBitmap(bitmap, canvas, ctx, printingFrame));\n}\nfunction drawBitmap(bitmap, canvas, ctx, printingFrame) {\n ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n printingFrame = false;\n}\nfunction Page() {\n const screenDimensions = useScreenDimensions();\n const emulatorDimensions = calculateSizeEmulator(screenDimensions);\n const canvasRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n function resizeCanvas() {\n const canvas = canvasRef.current;\n if (canvas == null) {\n return;\n }\n if (emulatorDimensions.width === undefined || emulatorDimensions.height === undefined) {\n return;\n }\n canvas.width = emulatorDimensions.width;\n canvas.height = emulatorDimensions.height;\n const ctx = canvas.getContext('2d');\n if (ctx == null) {\n return;\n }\n fillBlack(canvas, ctx);\n }\n ;\n const [hiddenFormSelectFiles, setHiddenFormSelectFiles] = react__WEBPACK_IMPORTED_MODULE_0__.useState(true);\n const [printingFrame, setPrintingFrame] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(resizeCanvas, [emulatorDimensions]);\n const refInputRom = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const refInputSaveState = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const onStartEmulation = (e) => {\n handleClickStartEmulationButton({\n e: e,\n setHiddenFormSelectFiles: setHiddenFormSelectFiles,\n inputRom: refInputRom.current,\n inputSaveState: refInputSaveState.current,\n canvas: canvasRef.current,\n setPrintingFrame: setPrintingFrame,\n printingFrame: printingFrame,\n });\n };\n const [hiddenMenu, setHiddenMenu] = react__WEBPACK_IMPORTED_MODULE_0__.useState(true);\n const [emulationStarted, setEmulationStarted] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);\n let firstMenuElement = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"vertical-padding\" }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"controls\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { ref: firstMenuElement, className: \"gear control\", onClick: (e) => {\n if (firstMenuElement.current == null) {\n console.log('wtf?');\n return;\n }\n firstMenuElement.current.focus();\n setHiddenMenu(false);\n } },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: \"/img/home.png\", alt: \"Go to menu. (House icon)\" })))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { style: { display: (hiddenMenu ? 'none' : '') }, className: \"overlay-menu-div\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu-div-header\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { onClick: (e) => setHiddenMenu(true), href: \"#\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: \"/img/close.png\", alt: \"Close button, a common 'x'\" }))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"ul\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { style: { display: emulationStarted ? 'none' : '' }, onClick: (e) => setHiddenFormSelectFiles(false), href: \"#\" }, \"Select rom\")),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"li\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { href: \"#\", onClick: (e) => setHiddenMenu(true) }, \"Exit\"))))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { style: { display: hiddenFormSelectFiles ? 'none' : '' }, className: \"overlay-menu-select-files overlay-menu-div\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu-div-header\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"a\", { onClick: (e) => setHiddenFormSelectFiles(true), href: \"#\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"img\", { src: \"/img/close.png\", alt: \"Close button, a common 'x'\" }))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_center_element__WEBPACK_IMPORTED_MODULE_1__[\"default\"], null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_form_select_files__WEBPACK_IMPORTED_MODULE_2__[\"default\"], { refInputRom: refInputRom, refInputSaveState: refInputSaveState, onStartEmulation: (e) => {\n setHiddenFormSelectFiles(true);\n setHiddenMenu(true);\n setEmulationStarted(true);\n onStartEmulation(e);\n } })))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_center_element__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { full: true },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_canvas_gba_emulator__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { canvasRef: canvasRef })))));\n}\nfunction getScreenDimensions() {\n return {\n width: document.body.clientWidth,\n height: document.body.clientHeight\n };\n}\nfunction useScreenDimensions() {\n const [screenDimensions, setScreenDimensions] = react__WEBPACK_IMPORTED_MODULE_0__.useState(getScreenDimensions());\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n function onResize() {\n setScreenDimensions(getScreenDimensions());\n }\n window.addEventListener(\"resize\", onResize);\n return () => {\n window.removeEventListener(\"resize\", onResize);\n };\n }, []);\n return screenDimensions;\n}\nfunction fillBlack(canvas, ctx) {\n ctx.beginPath();\n ctx.rect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#0E0E10';\n ctx.fill();\n}\n;\nfunction calculateSizeEmulator(screenDimensions) {\n if (screenDimensions.width === undefined || screenDimensions.height === undefined) {\n console.error(screenDimensions, 'screenDimensions has undefined fields');\n return {};\n }\n const width = screenDimensions.width;\n const height = screenDimensions.height;\n const emulatorDimensions = {};\n if (width < _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH || height < _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT) {\n return {\n width: _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH,\n height: _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT,\n };\n }\n const ratioWidth = width / _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH;\n const ratioHeight = height / _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT;\n if (ratioWidth < ratioHeight) {\n emulatorDimensions.width = _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH * ratioWidth;\n emulatorDimensions.height = _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT * ratioWidth;\n }\n else {\n emulatorDimensions.height = _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_HEIGHT * ratioHeight;\n emulatorDimensions.width = _constants__WEBPACK_IMPORTED_MODULE_5__.MIN_WIDTH * ratioHeight;\n }\n return emulatorDimensions;\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/page.tsx?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Page)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _components_center_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../components/center-element */ \"./js-src/components/center-element.tsx\");\n/* harmony import */ var _components_form_select_files__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../components/form-select-files */ \"./js-src/components/form-select-files.tsx\");\n/* harmony import */ var _components_canvas_gba_emulator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../components/canvas-gba-emulator */ \"./js-src/components/canvas-gba-emulator.tsx\");\n/* harmony import */ var _components_overlay_controls__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../components/overlay-controls */ \"./js-src/components/overlay-controls.tsx\");\n/* harmony import */ var _components_overlay_menu__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../components/overlay-menu */ \"./js-src/components/overlay-menu.tsx\");\n/* harmony import */ var _components_close_button__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../components/close-button */ \"./js-src/components/close-button.tsx\");\n/* harmony import */ var _endian__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../endian */ \"./js-src/endian.ts\");\n/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../constants */ \"./js-src/constants.ts\");\n\n\n\n\n\n\n\n\n\n;\nfunction handleClickStartEmulationButton({ e, inputRom, inputSaveState, canvas, printingFrame, setPrintingFrame, setEmulationStarted, setHiddenMenu, setHiddenFormSelectFiles }) {\n e.preventDefault();\n if (canvas == null) {\n alert('Canvas does not exists?');\n return;\n }\n const ctx = canvas.getContext('2d');\n if (ctx == null) {\n alert('Unable to create canvas context, doing nothing');\n return;\n }\n if (inputRom == null || inputSaveState == null || inputRom.files == null || inputSaveState.files == null) {\n alert('Unable to read the files ');\n return;\n }\n if (inputRom.files.length == 0) {\n alert('There is no rom still');\n return;\n }\n if (inputSaveState.files.length == 0) {\n alert('There is no savestate still');\n return;\n }\n const rom_file = inputRom.files[0];\n const savestate_file = inputSaveState.files[0];\n rom_file.arrayBuffer().then((rom_buffer) => {\n savestate_file.arrayBuffer().then((savestate_buffer) => {\n const rom_array = new Uint8Array(rom_buffer);\n const savestate_array = new Uint8Array(savestate_buffer);\n const websocket = new WebSocket(`ws://${window.location.host}/ws`);\n websocket.binaryType = 'arraybuffer';\n websocket.onclose = (message) => {\n setEmulationStarted(false);\n console.log('Closing websocket.');\n };\n websocket.onopen = () => {\n console.log('Opened websocket.');\n setEmulationStarted(true);\n sendHello(websocket, rom_array, savestate_array);\n setHiddenMenu(true);\n setHiddenFormSelectFiles(true);\n };\n setPrintingFrame(c => false);\n websocket.addEventListener('message', (event) => {\n onWebSocketPacket(event, canvas, ctx, printingFrame, setPrintingFrame);\n });\n });\n });\n}\nfunction concatU8Array(array1, array2) {\n const final_array = new Uint8Array(array1.length + array2.length);\n final_array.set(array1);\n final_array.set(array2, array1.length);\n return final_array;\n}\nfunction sendPacket(websocket, id, raw_data) {\n const packet_u8 = concatU8Array(concatU8Array(_endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].u64ToByteArrayBigEndian(id), _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].u64ToByteArrayBigEndian(BigInt(raw_data.length))), raw_data);\n const packet_buffer = packet_u8.buffer;\n console.log('Sending packet');\n websocket.send(packet_buffer);\n}\nfunction sendHello(websocket, rom_array, savestate_array) {\n console.log('Sending hello.');\n const length_rom = BigInt(rom_array.length);\n const length_savestate = BigInt(savestate_array.length);\n const raw_data = concatU8Array(concatU8Array(concatU8Array(_endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].u64ToByteArrayBigEndian(length_rom), rom_array), _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].u64ToByteArrayBigEndian(length_savestate)), savestate_array);\n sendPacket(websocket, _constants__WEBPACK_IMPORTED_MODULE_8__.PACKET_ID_HELLO, raw_data);\n}\nfunction onWebSocketPacket(event, canvas, ctx, printingFrame, setPrintingFrame) {\n const buffer = event.data;\n let packet_u8 = new Uint8Array(buffer);\n const id = _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].byteArrayToU64BigEndian(packet_u8.slice(0, 8));\n packet_u8 = packet_u8.slice(8, packet_u8.length);\n const size = _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].byteArrayToU64BigEndian(packet_u8.slice(0, 8));\n const raw_data = packet_u8.slice(8, packet_u8.length);\n packet_u8 = null;\n switch (id) {\n case _constants__WEBPACK_IMPORTED_MODULE_8__.PACKET_ID_SEND_FRAME:\n handleSendFrame(raw_data, canvas, ctx, printingFrame, setPrintingFrame);\n break;\n default:\n console.log(`Received unknown packet ${id}`);\n }\n}\nfunction handleSendFrame(raw_data, canvas, ctx, printingFrame, setPrintingFrame) {\n if (printingFrame) {\n return;\n }\n setPrintingFrame(c => true);\n let data = raw_data;\n const stride = _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].byteArrayToU32BigEndian(data.slice(0, 4));\n data = data.slice(4, data.length);\n const output_buffer_size = _endian__WEBPACK_IMPORTED_MODULE_7__[\"default\"].byteArrayToU64BigEndian(data.slice(0, 8));\n data = data.slice(8, data.length);\n const img_data = ctx.createImageData(_constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH, _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT);\n const img_data_u8 = new Uint8Array(img_data.data.buffer);\n for (let i = 0; i < data.length; i++) {\n if (i % 4 == 3) {\n img_data_u8[i] = 255;\n continue;\n }\n img_data_u8[i] = data[i];\n }\n data = null;\n createImageBitmap(img_data).then((bitmap) => drawBitmap(bitmap, canvas, ctx, printingFrame));\n}\nfunction drawBitmap(bitmap, canvas, ctx, printingFrame) {\n ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);\n printingFrame = false;\n}\nfunction Page() {\n const screenDimensions = useScreenDimensions();\n const emulatorDimensions = calculateSizeEmulator(screenDimensions);\n const canvasRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n function resizeCanvas() {\n const canvas = canvasRef.current;\n if (canvas == null) {\n return;\n }\n if (emulatorDimensions.width === undefined || emulatorDimensions.height === undefined) {\n return;\n }\n canvas.width = emulatorDimensions.width;\n canvas.height = emulatorDimensions.height;\n const ctx = canvas.getContext('2d');\n if (ctx == null) {\n return;\n }\n fillBlack(canvas, ctx);\n }\n ;\n const [hiddenFormSelectFiles, setHiddenFormSelectFiles] = react__WEBPACK_IMPORTED_MODULE_0__.useState(true);\n const [printingFrame, setPrintingFrame] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(resizeCanvas, [emulatorDimensions]);\n const refInputRom = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const refInputSaveState = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n const [emulationStarted, setEmulationStarted] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);\n const [hiddenMenu, setHiddenMenu] = react__WEBPACK_IMPORTED_MODULE_0__.useState(true);\n const onStartEmulation = (e) => {\n handleClickStartEmulationButton({\n e: e,\n setEmulationStarted: setEmulationStarted,\n inputRom: refInputRom.current,\n inputSaveState: refInputSaveState.current,\n canvas: canvasRef.current,\n setPrintingFrame: setPrintingFrame,\n printingFrame: printingFrame,\n setHiddenMenu: setHiddenMenu,\n setHiddenFormSelectFiles: setHiddenFormSelectFiles,\n });\n };\n let firstMenuElement = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);\n return (react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_overlay_controls__WEBPACK_IMPORTED_MODULE_4__[\"default\"], { firstMenuElement: firstMenuElement, setHiddenMenu: setHiddenMenu }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_overlay_menu__WEBPACK_IMPORTED_MODULE_5__[\"default\"], { hiddenMenu: hiddenMenu, setHiddenMenu: setHiddenMenu, emulationStarted: emulationStarted, setHiddenFormSelectFiles: setHiddenFormSelectFiles }),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { style: { display: hiddenFormSelectFiles ? 'none' : '' }, className: \"overlay-menu-select-files overlay-menu-div\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu-div-header\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_close_button__WEBPACK_IMPORTED_MODULE_6__[\"default\"], { onClick: () => setHiddenFormSelectFiles(true) })),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", { className: \"overlay-menu\" },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_center_element__WEBPACK_IMPORTED_MODULE_1__[\"default\"], null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_form_select_files__WEBPACK_IMPORTED_MODULE_2__[\"default\"], { refInputRom: refInputRom, refInputSaveState: refInputSaveState, onStartEmulation: (e) => {\n onStartEmulation(e);\n } })))),\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(\"div\", null,\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_center_element__WEBPACK_IMPORTED_MODULE_1__[\"default\"], { full: true },\n react__WEBPACK_IMPORTED_MODULE_0__.createElement(_components_canvas_gba_emulator__WEBPACK_IMPORTED_MODULE_3__[\"default\"], { canvasRef: canvasRef })))));\n}\nfunction getScreenDimensions() {\n return {\n width: document.body.clientWidth,\n height: document.body.clientHeight\n };\n}\nfunction useScreenDimensions() {\n const [screenDimensions, setScreenDimensions] = react__WEBPACK_IMPORTED_MODULE_0__.useState(getScreenDimensions());\n react__WEBPACK_IMPORTED_MODULE_0__.useEffect(() => {\n function onResize() {\n setScreenDimensions(getScreenDimensions());\n }\n window.addEventListener(\"resize\", onResize);\n return () => {\n window.removeEventListener(\"resize\", onResize);\n };\n }, []);\n return screenDimensions;\n}\nfunction fillBlack(canvas, ctx) {\n ctx.beginPath();\n ctx.rect(0, 0, canvas.width, canvas.height);\n ctx.fillStyle = '#0E0E10';\n ctx.fill();\n}\n;\nfunction calculateSizeEmulator(screenDimensions) {\n if (screenDimensions.width === undefined || screenDimensions.height === undefined) {\n console.error(screenDimensions, 'screenDimensions has undefined fields');\n return {};\n }\n const width = screenDimensions.width;\n const height = screenDimensions.height;\n const emulatorDimensions = {};\n if (width < _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH || height < _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT) {\n return {\n width: _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH,\n height: _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT,\n };\n }\n const ratioWidth = width / _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH;\n const ratioHeight = height / _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT;\n if (ratioWidth < ratioHeight) {\n emulatorDimensions.width = _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH * ratioWidth;\n emulatorDimensions.height = _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT * ratioWidth;\n }\n else {\n emulatorDimensions.height = _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_HEIGHT * ratioHeight;\n emulatorDimensions.width = _constants__WEBPACK_IMPORTED_MODULE_8__.MIN_WIDTH * ratioHeight;\n }\n return emulatorDimensions;\n}\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/components/page.tsx?"); /***/ }), @@ -126,7 +156,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac \*****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"MIN_HEIGHT\": () => (/* binding */ MIN_HEIGHT),\n/* harmony export */ \"MIN_WIDTH\": () => (/* binding */ MIN_WIDTH),\n/* harmony export */ \"PACKET_ID_HELLO\": () => (/* binding */ PACKET_ID_HELLO),\n/* harmony export */ \"PACKET_ID_SEND_FRAME\": () => (/* binding */ PACKET_ID_SEND_FRAME),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst MIN_WIDTH = 240;\nconst MIN_HEIGHT = 160;\nconst PACKET_ID_HELLO = 0n;\nconst PACKET_ID_SEND_FRAME = 1n;\nclass Constants {\n}\nConstants.MIN_WIDTH = MIN_WIDTH;\nConstants.MIN_HEIGHT = MIN_HEIGHT;\nConstants.PACKET_ID_HELLO = PACKET_ID_HELLO;\nConstants.PACKET_ID_SEND_FRAME = PACKET_ID_SEND_FRAME;\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Constants);\n;\nConstants.MIN_WIDTH = MIN_WIDTH;\nConstants.MIN_HEIGHT = MIN_HEIGHT;\nConstants.PACKET_ID_HELLO = PACKET_ID_HELLO;\nConstants.PACKET_ID_SEND_FRAME = PACKET_ID_SEND_FRAME;\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/constants.ts?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"CLOSE_BUTTON_IMAGE\": () => (/* binding */ CLOSE_BUTTON_IMAGE),\n/* harmony export */ \"HOME_BUTTON_IMAGE\": () => (/* binding */ HOME_BUTTON_IMAGE),\n/* harmony export */ \"MIN_HEIGHT\": () => (/* binding */ MIN_HEIGHT),\n/* harmony export */ \"MIN_WIDTH\": () => (/* binding */ MIN_WIDTH),\n/* harmony export */ \"PACKET_ID_HELLO\": () => (/* binding */ PACKET_ID_HELLO),\n/* harmony export */ \"PACKET_ID_SEND_FRAME\": () => (/* binding */ PACKET_ID_SEND_FRAME),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst MIN_WIDTH = 240;\nconst MIN_HEIGHT = 160;\nconst PACKET_ID_HELLO = 0n;\nconst PACKET_ID_SEND_FRAME = 1n;\nconst CLOSE_BUTTON_IMAGE = \"/img/close.png\";\nconst HOME_BUTTON_IMAGE = \"/img/home.png\";\nclass Constants {\n}\nConstants.MIN_WIDTH = MIN_WIDTH;\nConstants.MIN_HEIGHT = MIN_HEIGHT;\nConstants.PACKET_ID_HELLO = PACKET_ID_HELLO;\nConstants.PACKET_ID_SEND_FRAME = PACKET_ID_SEND_FRAME;\nConstants.CLOSE_BUTTON_IMAGE = CLOSE_BUTTON_IMAGE;\nConstants.HOME_BUTTON_IMAGE = HOME_BUTTON_IMAGE;\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Constants);\n;\n\n\n//# sourceURL=webpack://MSGBA-Web/./js-src/constants.ts?"); /***/ }),