Use EmulatorJs instead of Byuu

This commit is contained in:
Dustin Brett 2022-08-23 23:06:17 -07:00
parent 7047f3d755
commit 952a867483
75 changed files with 856 additions and 9940 deletions

View File

@ -134,13 +134,6 @@ docker run -dp 3000:3000 --rm --name daedalos daedalos
- Back/Forward & Reload
- Google search via Address bar
### [Byuu](https://github.com/Wizcorp/byuu-web) (**_.gen, .nes, .sfc, .smc, .smd_**)
- NES/SNES/Sega Genesis Emulator
- Automatic save states on close
- /Users/Public/Snapshots
- Automatic window resize
### [DevTools](https://eruda.liriliri.io/)
- Console, Elements, Network, Resources, Sources, DOM

View File

@ -1,5 +0,0 @@
import styled from "styled-components";
const StyledByuu = styled.div``;
export default StyledByuu;

View File

@ -1,35 +0,0 @@
import type { Emulator } from "byuu";
/* eslint-disable sort-keys-fix/sort-keys-fix */
export const keyMap: Record<string, string> = {
ArrowUp: "Up",
ArrowDown: "Down",
ArrowLeft: "Left",
ArrowRight: "Right",
m: "Mode",
s: "Select",
Enter: "Start",
a: "A",
b: "B",
c: "C",
x: "X",
y: "Y",
z: "Z",
l: "L",
r: "R",
};
export const prettyKey: Record<string, string> = {
ArrowUp: "↑",
ArrowDown: "↓",
ArrowLeft: "←",
ArrowRight: "→",
};
export const prettyEmulator: Record<Emulator, string> = {
Famicom: "NES",
"Super Famicom": "SNES",
"Mega Drive": "Sega Genesis",
};
export const saveExtension = ".sav";

View File

@ -1,9 +0,0 @@
import ContainerComponent from "components/apps/AppContainer";
import StyledByuu from "components/apps/Byuu/StyledByuu";
import useByuu from "components/apps/Byuu/useByuu";
import type { ComponentProcessProps } from "components/system/Apps/RenderComponent";
const Byuu: FC<ComponentProcessProps> = ({ id }) =>
ContainerComponent(id, useByuu, StyledByuu);
export default Byuu;

View File

@ -1,184 +0,0 @@
import type Byuu from "byuu";
import type { Emulator } from "byuu";
import {
keyMap,
prettyEmulator,
prettyKey,
saveExtension,
} from "components/apps/Byuu/config";
import useTitle from "components/system/Window/useTitle";
import useWindowSize from "components/system/Window/useWindowSize";
import { useFileSystem } from "contexts/fileSystem";
import { useProcesses } from "contexts/process";
import { basename, join } from "path";
import type React from "react";
import { useCallback, useEffect, useRef } from "react";
import { SAVE_PATH } from "utils/constants";
import { haltEvent, loadFiles } from "utils/functions";
declare global {
interface Window {
byuu?: typeof Byuu;
byuuWasmPath?: string;
}
}
const pressKey =
(controller: string, buttons: string[]) =>
({ key, type }: KeyboardEvent) => {
if (keyMap[key] && buttons.includes(keyMap[key])) {
window.byuu?.setButton(
controller,
keyMap[key],
type === "keydown" ? 1 : 0
);
}
};
const useByuu = (
id: string,
url: string,
containerRef: React.MutableRefObject<HTMLDivElement | null>,
setLoading: React.Dispatch<React.SetStateAction<boolean>>
): void => {
const { exists, mkdirRecursive, readFile, updateFolder, writeFile } =
useFileSystem();
const { appendFileToTitle } = useTitle(id);
const { updateWindowSize } = useWindowSize(id);
const { processes: { [id]: { libs = [] } = {} } = {} } = useProcesses();
const loadedUrl = useRef<string>("");
const saveState = useRef<() => Promise<void>>();
const loadFile = useCallback(
async (fileUrl: string) => {
if (!window.byuu || !containerRef.current) return;
if (window.byuu.isStarted()) {
saveState.current?.();
window.byuu.unload();
}
window.byuu.setEmulatorForFilename(fileUrl);
const romInfo = window.byuu.load(await readFile(fileUrl));
const {
emulator: {
buttons = [],
name: emulatorName = "",
ports: [controllerName] = [],
} = {},
} = romInfo;
const gameSavePath = join(
SAVE_PATH,
`${basename(fileUrl)}${saveExtension}`
);
if (await exists(gameSavePath)) {
window.byuu.stateLoad(await readFile(gameSavePath));
}
const canvas = window.byuu.getCanvas();
canvas.tabIndex = -1;
canvas.title = Object.entries(keyMap)
.map(([key, button]) =>
buttons.includes(button)
? `${button} = ${prettyKey[key] || key}`
: false
)
.filter(Boolean)
.join("\n");
canvas.addEventListener("keydown", pressKey(controllerName, buttons));
canvas.addEventListener("keyup", pressKey(controllerName, buttons));
canvas.addEventListener("contextmenu", haltEvent);
if (
!window.byuu.connectPeripheral(
controllerName,
emulatorName === "Mega Drive" ? "Fighting Pad" : "Gamepad"
)
) {
return;
}
const baseName = basename(url);
window.byuu.start();
appendFileToTitle(
`${baseName} (${prettyEmulator[emulatorName as Emulator]})`
);
const multipler = canvas.width > 256 ? 1 : 2;
updateWindowSize(canvas.height * multipler, canvas.width * multipler);
saveState.current = async () => {
if (!window.byuu) return;
const state = await window.byuu.stateSave();
const saveName = `${baseName}${saveExtension}`;
if (!(await exists(SAVE_PATH))) await mkdirRecursive(SAVE_PATH);
if (
await writeFile(join(SAVE_PATH, saveName), Buffer.from(state), true)
) {
updateFolder(SAVE_PATH, saveName);
}
};
},
[
appendFileToTitle,
containerRef,
exists,
mkdirRecursive,
readFile,
updateFolder,
updateWindowSize,
url,
writeFile,
]
);
const loadByuu = useCallback(async () => {
window.byuuWasmPath = "/Program Files/Byuu/byuu-web-lib.wasm";
await loadFiles(libs);
if (!containerRef.current) return;
await window.byuu?.initialize(containerRef.current);
setLoading(false);
if (url) loadFile(url);
else {
try {
window.byuu?.terminate();
} catch {
// Ignore errors from pre-post-cleanup
}
}
}, [containerRef, libs, loadFile, setLoading, url]);
useEffect(() => {
if (loadedUrl.current !== url || !url) {
loadedUrl.current = url;
loadByuu();
}
}, [loadByuu, url]);
useEffect(
() => () => {
if (window.byuu?.isStarted()) {
if (saveState.current) {
setTimeout(
() => saveState.current?.().then(() => window.byuu?.terminate()),
1000
);
} else {
window.byuu?.terminate();
}
}
},
[]
);
};
export default useByuu;

View File

@ -0,0 +1,5 @@
import styled from "styled-components";
const StyledEmulator = styled.div``;
export default StyledEmulator;

View File

@ -0,0 +1,87 @@
export type Core = {
core: string;
ext: string[];
};
export const emulatorCores: Record<string, Core> = {
"Atari 2600": {
core: "atari2600",
ext: [".a26"],
},
"Atari 5200": {
core: "atari5200",
ext: [".a52"],
},
"Atari 7800": {
core: "atari7800",
ext: [".a78"],
},
"Atari Jaguar": {
core: "jaguar",
ext: [".j64"],
},
"Atari Lynx": {
core: "lynx",
ext: [".lnx"],
},
"Neo Geo Pocket": {
core: "ngp",
ext: [".ngp"],
},
"Nintendo 64": {
core: "n64",
ext: [".n64"],
},
"Nintendo DS": {
core: "nds",
ext: [".nds"],
},
"Nintendo Entertainment System": {
core: "nes",
ext: [".nes"],
},
"Nintendo Game Boy": {
core: "gb",
ext: [".gb"],
},
"Nintendo Game Boy Advance": {
core: "gba",
ext: [".gba"],
},
"Nintendo Game Boy Color": {
core: "gb",
ext: [".gbc"],
},
"PC Engine": {
core: "pce",
ext: [".pce"],
},
"Sega 32X": {
core: "sega32x",
ext: [".32x"],
},
"Sega Game Gear": {
core: "segaGG",
ext: [".gg"], // Only working when zipped?
},
"Sega Genesis / Mega Drive": {
core: "segaMD",
ext: [".gen", ".md", ".smd"],
},
"Sega Master System": {
core: "segaMS",
ext: [".sms"], // Only working when zipped?
},
"Super Nintendo Entertainment System": {
core: "snes",
ext: [".sfc", ".smc"],
},
"Virtual Boy": {
core: "vb",
ext: [".vb"],
},
WonderSwam: {
core: "ws",
ext: [".wsc"],
},
};

View File

@ -0,0 +1,9 @@
import ContainerComponent from "components/apps/AppContainer";
import StyledEmulator from "components/apps/Emulator/StyledEmulator";
import useEmulator from "components/apps/Emulator/useEmulator";
import type { ComponentProcessProps } from "components/system/Apps/RenderComponent";
const Emulator: FC<ComponentProcessProps> = ({ id }) =>
ContainerComponent(id, useEmulator, StyledEmulator, <div id="emulator" />);
export default Emulator;

View File

@ -0,0 +1,66 @@
export type Emulator = {
elements: {
buttons: {
saveState?: HTMLButtonElement;
};
};
loadState?: (state: Buffer) => void;
};
declare global {
interface Window {
Browser?: {
mainLoop: {
queue: unknown[];
runIter: () => void;
scheduler: () => void;
};
setCanvasSize: () => void;
};
EJS_Buttons?: {
cacheManage: boolean;
loadState: boolean;
quickLoad: boolean;
quickSave: boolean;
saveState: boolean;
screenRecord: boolean;
screenshot: boolean;
};
EJS_biosUrl?: string;
EJS_core?: string;
EJS_emulator?: {
on: (event: string, callback: () => void) => void;
};
EJS_gameName?: string;
EJS_gameUrl?: string;
EJS_onGameStart?: (
event: Event & {
detail: {
emulator: Emulator;
};
}
) => void;
EJS_onSaveState?: (event: {
screenshot: Uint8Array;
state: Uint8Array;
}) => void;
EJS_pathtodata?: string;
EJS_player?: string;
EJS_startOnLoaded?: boolean;
EJS_terminate?: () => void;
FS: unknown;
GL?: {
newRenderingFrameStarted: () => void;
};
IDBFS?: {
reconcile: () => void;
};
JSEvents?: {
runDeferredCalls: () => void;
};
RI?: {
contexts: unknown[];
};
saveSaveFiles?: () => void;
}
}

View File

@ -0,0 +1,146 @@
import { emulatorCores } from "components/apps/Emulator/config";
import type { Emulator } from "components/apps/Emulator/types";
import useTitle from "components/system/Window/useTitle";
import { useFileSystem } from "contexts/fileSystem";
import { basename, dirname, extname, join } from "path";
import { useCallback, useEffect, useRef } from "react";
import { ICON_CACHE, ICON_CACHE_EXTENSION, SAVE_PATH } from "utils/constants";
import { bufferToUrl, loadFiles } from "utils/functions";
const getCore = (extension: string): string => {
const lcExt = extension.toLowerCase();
const [, { core = "" } = {}] =
Object.entries(emulatorCores).find(([, { ext }]) => ext.includes(lcExt)) ||
[];
return core;
};
const stubEmulatorDeps = (): void => {
window.Browser = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
mainLoop: { queue: [], runIter: () => {}, scheduler: () => {} },
// eslint-disable-next-line @typescript-eslint/no-empty-function
setCanvasSize: () => {},
};
window.IDBFS = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
reconcile: () => {},
};
window.JSEvents = {
// eslint-disable-next-line @typescript-eslint/no-empty-function
runDeferredCalls: () => {},
};
// eslint-disable-next-line @typescript-eslint/no-empty-function
window.FS = {};
// eslint-disable-next-line @typescript-eslint/no-empty-function
window.GL = { newRenderingFrameStarted: () => {} };
// eslint-disable-next-line @typescript-eslint/no-empty-function
window.saveSaveFiles = () => {};
window.RI = {
contexts: [],
};
};
const useEmulator = (
id: string,
url: string,
_containerRef: React.MutableRefObject<HTMLDivElement | null>,
setLoading: React.Dispatch<React.SetStateAction<boolean>>,
loading: boolean
): void => {
const { exists, mkdirRecursive, readFile, updateFolder, writeFile } =
useFileSystem();
const { prependFileToTitle } = useTitle(id);
const emulatorRef = useRef<Emulator>();
const initRef = useRef(false);
const loadRom = useCallback(async () => {
if (initRef.current || !url) return;
initRef.current = true;
const ext = extname(url);
window.EJS_gameName = basename(url, ext);
window.EJS_gameUrl = bufferToUrl(await readFile(url));
window.EJS_core = getCore(ext);
const saveName = `${basename(url)}.sav`;
const savePath = join(SAVE_PATH, saveName);
window.EJS_onGameStart = ({ detail: { emulator: currentEmulator } }) => {
const loadState = async (): Promise<void> => {
if (await exists(savePath)) {
currentEmulator.loadState?.(await readFile(savePath));
}
setLoading(false);
emulatorRef.current = currentEmulator;
};
loadState();
};
window.EJS_onSaveState = ({ screenshot, state }) => {
window.EJS_terminate?.();
stubEmulatorDeps();
const saveState = async (): Promise<void> => {
if (!(await exists(SAVE_PATH))) await mkdirRecursive(SAVE_PATH);
if (await writeFile(savePath, Buffer.from(state), true)) {
const iconCacheRootPath = join(ICON_CACHE, dirname(savePath));
const iconCachePath = join(
ICON_CACHE,
`${savePath}${ICON_CACHE_EXTENSION}`
);
if (!(await exists(iconCacheRootPath))) {
await mkdirRecursive(iconCacheRootPath);
}
await writeFile(iconCachePath, Buffer.from(screenshot));
updateFolder(SAVE_PATH, saveName);
}
};
if (state) saveState();
};
window.EJS_player = "#emulator";
window.EJS_biosUrl = "";
window.EJS_pathtodata = "Program Files/EmulatorJs/";
window.EJS_startOnLoaded = true;
window.EJS_Buttons = {
cacheManage: false,
loadState: false,
quickLoad: false,
quickSave: false,
saveState: false,
screenRecord: false,
screenshot: false,
};
await loadFiles(["Program Files/EmulatorJs/loader.js"], undefined, true);
prependFileToTitle(window.EJS_gameName);
}, [
exists,
mkdirRecursive,
prependFileToTitle,
readFile,
setLoading,
updateFolder,
url,
writeFile,
]);
useEffect(() => {
if (!url) setLoading(false);
else loadRom();
return () => {
if (!loading) {
emulatorRef.current?.elements.buttons.saveState?.click();
}
};
}, [loadRom, loading, setLoading, url]);
};
export default useEmulator;

View File

@ -1,3 +1,4 @@
import { emulatorCores } from "components/apps/Emulator/config";
import { EDITABLE_IMAGE_FILE_EXTENSIONS } from "utils/constants";
type Extension = {
@ -25,6 +26,11 @@ const types = {
process: ["V86"],
type: "Disc Image File",
},
Emulator: {
icon: "emulator",
process: ["Emulator"],
type: "Game ROM File",
},
FutureSplash: {
process: ["Ruffle"],
type: "FutureSplash File",
@ -60,11 +66,6 @@ const types = {
icon: "audio",
process: ["Webamp"],
},
NintendoRom: {
icon: "rom",
process: ["Byuu"],
type: "Nintendo ROM File",
},
PdfDocument: {
icon: "pdf",
process: ["PDF"],
@ -76,20 +77,10 @@ const types = {
process: ["Terminal", ...TEXT_EDITORS],
type: "Python File",
},
SegaGenesisRom: {
icon: "rom",
process: ["Byuu"],
type: "Sega Genesis ROM File",
},
ShockwaveFlash: {
process: ["Ruffle"],
type: "Shockwave Flash File",
},
SuperNintendoRom: {
icon: "rom",
process: ["Byuu"],
type: "Super Nintendo ROM File",
},
SvgFile: {
process: ["Photos", ...TEXT_EDITORS],
type: "Scalable Vector Graphics File",
@ -114,7 +105,6 @@ const types = {
const extensions: Record<string, Extension> = {
".asx": types.AudioPlaylist,
".exe": types.Application,
".gen": types.SegaGenesisRom,
".htm": types.HtmlDocument,
".html": types.HtmlDocument,
".img": types.DiscImage,
@ -124,13 +114,9 @@ const extensions: Record<string, Extension> = {
".m3u8": types.MediaPlaylist,
".md": types.Markdown,
".mp3": types.Music,
".nes": types.NintendoRom,
".pdf": types.PdfDocument,
".pls": types.AudioPlaylist,
".py": types.PythonFile,
".sfc": types.SuperNintendoRom,
".smc": types.SuperNintendoRom,
".smd": types.SegaGenesisRom,
".spl": types.FutureSplash,
".svg": types.SvgFile,
".swf": types.ShockwaveFlash,
@ -139,8 +125,22 @@ const extensions: Record<string, Extension> = {
".zip": types.ZipFile,
};
EDITABLE_IMAGE_FILE_EXTENSIONS.forEach((extension) => {
extensions[extension] = types.GraphicsEditor;
});
const addType =
(type: Extension) =>
(extension: string): void => {
if (type.process) {
if (extensions[extension]) {
extensions[extension].process.push(...type.process);
} else {
extensions[extension] = type;
}
}
};
EDITABLE_IMAGE_FILE_EXTENSIONS.forEach(addType(types.GraphicsEditor));
Object.values(emulatorCores).forEach(({ ext }) =>
ext.forEach(addType(types.Emulator))
);
export default extensions;

View File

@ -239,7 +239,7 @@ export const getInfoWithExtension = (
const subIcons: string[] = [];
const getInfoByFileExtension = (
icon?: string,
getIcon?: (signal: AbortSignal) => void
getIcon?: true | ((signal: AbortSignal) => void)
): void =>
callback({
getIcon,
@ -496,6 +496,8 @@ export const getInfoWithExtension = (
}
})
);
} else if (extension === ".sav") {
getInfoByFileExtension(UNKNOWN_ICON_PATH, true);
} else {
getInfoByFileExtension();
}

View File

@ -321,7 +321,11 @@ const FileEntry: FC<FileEntryProps> = ({
// Ignore issues deleting bad cached icon
}
}
} else if (!isDynamicIconLoaded.current && buttonRef.current) {
} else if (
!isDynamicIconLoaded.current &&
buttonRef.current &&
typeof getIcon === "function"
) {
isDynamicIconLoaded.current = true;
new IntersectionObserver(
([{ intersectionRatio }], observer) => {

View File

@ -9,7 +9,7 @@ import { MOUNTABLE_EXTENSIONS } from "utils/constants";
export type FileInfo = {
comment?: string;
getIcon?: (signal: AbortSignal) => void;
getIcon?: true | ((signal: AbortSignal) => void);
icon: string;
pid: string;
subIcons?: string[];

View File

@ -31,20 +31,6 @@ const directory: Processes = {
icon: "/System/Icons/chromium.webp",
title: "Browser",
},
Byuu: {
Component: dynamic(() => import("components/apps/Byuu")),
autoSizing: true,
background: "#000",
defaultSize: {
height: 240,
width: 256,
},
icon: "/System/Icons/byuu.webp",
libs: ["/Program Files/Byuu/byuu.js"],
lockAspectRatio: true,
singleton: true,
title: "Byuu",
},
Chess: {
Component: dynamic(() => import("components/apps/Chess")),
allowResizing: false,
@ -90,6 +76,18 @@ const directory: Processes = {
singleton: true,
title: "DevTools",
},
Emulator: {
Component: dynamic(() => import("components/apps/Emulator")),
background: "#000",
defaultSize: {
height: 400,
width: 600,
},
icon: "/System/Icons/emulator.webp",
lockAspectRatio: true,
singleton: true,
title: "Emulator",
},
FileExplorer: {
Component: dynamic(() => import("components/apps/FileExplorer")),
background: "#202020",

View File

@ -88,7 +88,6 @@
"@typescript-eslint/eslint-plugin": "^5.34.0",
"@typescript-eslint/parser": "^5.34.0",
"browserfs": "https://github.com/jvilk/BrowserFS.git",
"byuu": "^0.16.0",
"emulators": "^0.73.7",
"emulators-ui": "^0.73.7",
"eruda": "^2.5.0",

View File

@ -60,7 +60,7 @@ This project is greatly augmented by code from the open source community. Thank
- [ImageMagick](https://github.com/KnicKnic/WASM-ImageMagick)
- [Lunr](https://github.com/olivernn/lunr.js)
- [Web eSheep](https://github.com/Adrianotiger/web-esheep)
- [Byuu](https://github.com/Wizcorp/byuu-web)
- [emulatorjs](https://github.com/ethanaobrien/emulatorjs)
- [SheetJS](https://github.com/SheetJS/sheetjs)
- [Vim.js](https://github.com/coolwanglu/vim.js)
- [DX-Ball](https://habr.com/en/post/147339/)

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,97 @@
(async function () {
let VERSION = 23.5;
let scriptTag = document.getElementsByTagName("script")[0];
function loadStyle(file) {
return new Promise(function (resolve, reject) {
let css = document.createElement("link");
css.rel = "stylesheet";
css.href = (function () {
if (
"undefined" != typeof EJS_paths &&
typeof EJS_paths[file] == "string"
) {
return EJS_paths[file];
} else if ("undefined" != typeof EJS_pathtodata) {
if (!EJS_pathtodata.endsWith("/")) EJS_pathtodata += "/";
return EJS_pathtodata + file + "?v=" + VERSION;
} else {
return file + "?v=" + VERSION;
}
})();
css.onload = resolve;
document.head.appendChild(css);
});
}
function loadScript(file) {
return new Promise(function (resolve, reject) {
let script = document.createElement("script");
script.src = (function () {
if (
"undefined" != typeof EJS_paths &&
typeof EJS_paths[file] == "string"
) {
return EJS_paths[file];
} else if ("undefined" != typeof EJS_pathtodata) {
if (!EJS_pathtodata.endsWith("/")) EJS_pathtodata += "/";
return EJS_pathtodata + file + "?v=" + VERSION;
} else {
return file + "?v=" + VERSION;
}
})();
scriptTag.parentNode.insertBefore(script, scriptTag);
script.onload = resolve;
});
}
if ("undefined" != typeof EJS_DEBUG_XX && true === EJS_DEBUG_XX) {
await loadStyle("emu-css.css");
await loadScript("emu-main.js");
await loadScript("emulator.js");
} else {
await loadStyle("emu-css.min.css");
await loadScript("emulator.min.js");
}
let config = {};
config.gameUrl = EJS_gameUrl;
"undefined" != typeof EJS_mameCore && (config.mameCore = EJS_mameCore);
"undefined" != typeof EJS_biosUrl && (config.biosUrl = EJS_biosUrl);
"undefined" != typeof EJS_gameID && (config.gameId = EJS_gameID);
"undefined" != typeof EJS_gameParentUrl &&
(config.gameParentUrl = EJS_gameParentUrl);
"undefined" != typeof EJS_gamePatchUrl &&
(config.gamePatchUrl = EJS_gamePatchUrl);
"undefined" != typeof EJS_AdUrl && (config.adUrl = EJS_AdUrl);
"undefined" != typeof EJS_paths && (config.paths = EJS_paths);
"undefined" != typeof EJS_netplayUrl && (config.netplayUrl = EJS_netplayUrl);
"undefined" != typeof EJS_startOnLoaded &&
(config.startOnLoad = EJS_startOnLoaded);
"undefined" != typeof EJS_core && (config.system = EJS_core);
"undefined" != typeof EJS_oldCores && (config.oldCores = EJS_oldCores);
"undefined" != typeof EJS_loadStateURL &&
(config.loadStateOnStart = EJS_loadStateURL);
"undefined" != typeof EJS_language && (config.lang = EJS_language);
"undefined" != typeof EJS_noAutoCloseAd &&
(config.noAutoAdClose = EJS_noAutoCloseAd);
"undefined" != typeof EJS_VirtualGamepadSettings &&
(config.VirtualGamepadSettings = EJS_VirtualGamepadSettings);
"undefined" != typeof EJS_oldEJSNetplayServer &&
(config.oldNetplayServer = EJS_oldEJSNetplayServer);
"undefined" != typeof EJS_Buttons && (config.buttons = EJS_Buttons);
"undefined" != typeof EJS_Settings && (config.settings = EJS_Settings);
config.onsavestate = null;
config.onloadstate = null;
"undefined" != typeof EJS_onSaveState &&
(config.onsavestate = EJS_onSaveState);
"undefined" != typeof EJS_onLoadState &&
(config.onloadstate = EJS_onLoadState);
"undefined" != typeof EJS_lightgun && (config.lightgun = EJS_lightgun);
"undefined" != typeof EJS_gameName && (config.gameName = EJS_gameName);
"undefined" != typeof EJS_pathtodata && (config.dataPath = EJS_pathtodata);
"undefined" != typeof EJS_mouse && (config.mouse = EJS_mouse);
"undefined" != typeof EJS_multitap && (config.multitap = EJS_multitap);
"undefined" != typeof EJS_playerName && (config.playerName = EJS_playerName);
"undefined" != typeof EJS_cheats && (config.cheats = EJS_cheats);
"undefined" != typeof EJS_color && (config.color = EJS_color);
window.EJS_emulator = await new EJS(EJS_player, config);
"undefined" != typeof EJS_onGameStart &&
EJS_emulator.on("start-game", EJS_onGameStart);
})();

View File

@ -0,0 +1,197 @@
{
"i18n": {
"restart": "-Restart",
"play": "-Play",
"pause": "-Pause",
"played": "-Played",
"volume": "-Volume",
"mute": "-Mute (F9)",
"unmute": "-Unmute (F9)",
"enterFullscreen": "-Enter fullscreen",
"exitFullscreen": "-Exit fullscreen",
"settings": "-Settings",
"saveState": "-Save State (Shift + F2)",
"loadState": "-Load State (Shift + F4)",
"screenRecord": "-Start Screen Recording",
"netplay": "-Netplay",
"gamepad": "-Control Settings",
"cheat": "-Cheats",
"menuBack": "-Go back to previous menu",
"normal": "-Normal",
"all": "-All",
"reset": "-Reset",
"disabled": "-Disabled",
"enabled": "-Enabled",
"playNow": "-Play Now"
},
"normalOptions": {
"shader": {
"label": "-Shader",
"options": {
"disabled": "-Disabled",
"2xScaleHQ.glslp": "-2xScaleHQ",
"4xScaleHQ.glslp": "-4xScaleHQ",
"crt-easymode.glslp": "-CRT easymode",
"crt-aperture.glslp": "-CRT aperture",
"crt-geom.glslp": "-CRT geom"
},
"default": "disabled"
},
"virtual-gamepad": {
"label": "-Virtual Gamepad",
"options": {
"disabled": "-Disabled",
"enabled": "-Enabled"
},
"default": "enabled"
}
},
"Control Settings": "-Control Settings",
"Player 1": "-Player 1",
"Player 2": "-Player 2",
"Player 3": "-Player 3",
"Player 4": "-Player 4",
"Update": "-Update",
"Reset": "-Reset",
"Clear": "-Clear",
"Cancel": "-Cancel",
"Close": "-Close",
"Empty": "-Empty",
"Loading": "-Loading",
"Submit": "-Submit",
"Description": "-Description",
"Code": "-Code",
"Add Cheat Code": "-Add Cheat Code",
"OK": "-OK",
"Add Cheat": "-Add Cheat",
"Cache Manager": "-Cache Manager",
"Press keyboard or gamepad": "-Press keyboard or gamepad",
"Gamepad": "-Gamepad",
"Keyboard": "-Keyboard",
"Set": "-Set",
"QUICK SAVE STATE": "-QUICK SAVE STATE",
"QUICK LOAD STATE": "-QUICK LOAD STATE",
"CHANGE STATE SLOT": "-CHANGE STATE SLOT",
"INSERT COIN": "-INSERT COIN",
"Press keyboard or gamepad": "-Press keyboard or gamepad",
"Press escape (esc) to clear": "-Press escape (esc) to clear",
"Netplay": "-Netplay",
"Rooms": "-Rooms",
"Players": "-Players",
"Player": "-Player",
"Room Name": "-Room Name",
"Password": "-Password",
"Name": "-Name",
"Quit Room": "-Quit Room",
"Create a Room": "-Create a Room",
"Set Player Name": "-Set Player Name",
"Player Name": "-Player Name",
"Room Name": "-Room Name",
"Create a Room": "-Create a Room",
"Password (optional)": "-Password (optional)",
"Select": "-Select",
"Start": "-Start",
"Menu": "-Menu",
"Decompress Game Core": "-Decompress Game Core",
"Decompress Game Data": "-Decompress Game Data",
"Decompress Game Patch": "-Decompress Game Patch",
"Download Game Data": "-Download Game Data",
"Download Game Core": "-Download Game Core",
"Network Error": "-Network Error",
"Default": "-Default",
"default": "-default",
"Save State Location": "-Save State Location",
"Save State Slot": "-Save State Slot",
"Color Palette": "-Color Palette",
"No Sprite Limit": "-No Sprite Limit",
"Enabled": "-Enabled",
"Disabled": "-Disabled",
"enabled": "-enabled",
"disabled": "-disabled",
"Low": "-Low",
"High": "-High",
"Very High": "-Very High",
"4 Players Support": "-4 Players Support",
"Turbo Enable": "-Turbo Enable",
"None": "-None",
"Both": "-Both",
"Region": "-Region",
"SuperFX Overclock": "-SuperFX Overclock",
"Sound Quality": "-Sound Quality",
"GB Colorization": "-GB Colorization",
"auto": "-auto",
"internal": "-internal",
"Internal Palette": "-Internal Palette",
"GBC - Blue": "-GBC - Blue",
"GBC - Brown": "-GBC - Brown",
"GBC - Dark Blue": "-GBC - Dark Blue",
"GBC - Dark Brown": "-GBC - Dark Brown",
"GBC - Dark Green": "-GBC - Dark Green",
"GBC - Grayscale": "-GBC - Grayscale",
"GBC - Green": "-GBC - Green",
"GBC - Inverted": "-GBC - Inverted",
"GBC - Orange": "-GBC - Orange",
"GBC - Red": "-GBC - Red",
"GBC - Pastel Mix": "-GBC - Pastel Mix",
"GBC - Yellow": "-GBC - Yellow",
"Frameskip": "-Frameskip",
"Solar sensor level": "-Solar sensor level",
"Enable Turbo Buttons": "-Enable Turbo Buttons",
"Turbo Delay in frames": "-Turbo Delay in frames",
"Auto": "-Auto",
"Aspect Ratio (Need to refresh page)": "-Aspect Ratio (Need to refresh page)",
"16:9 Resolution": "-16:9 Resolution",
"4:3 Resolution": "-4:3 Resolution",
"Player 1 Pak": "-Player 1 Pak",
"Player 2 Pak": "-Player 2 Pak",
"Player 3 Pak": "-Player 3 Pak",
"Player 4 Pak": "-Player 4 Pak",
"none": "-none",
"memory": "-memory",
"rumble": "-rumble",
"Screen layout": "-Screen layout",
"right/left": "-right/left",
"left/right": "-left/right",
"bottom/top": "-bottom/top",
"top/bottom": "-top/bottom",
"top only": "-top only",
"bottom only": "-bottom only",
"quick switch": "-quick switch",
"hybrid/bottom": "-hybrid/bottom",
"hybrid/top": "-hybrid/top",
"Screen Rotation": "-Screen Rotation",
"CPU speed": "-CPU speed",
"Sound output": "-Sound output",
"mono": "-mono",
"stereo": "-stereo",
"OFF": "-OFF",
"ON": "-ON",
"Fast Blitter": "-Fast Blitter",
"Bios": "-Bios",
"Enable second memory card": "-Enable second memory card",
"Pad 1 Type": "-Pad 1 Type",
"Pad 2 Type": "-Pad 2 Type",
"Pad 3 Type": "-Pad 3 Type",
"Pad 4 Type": "-Pad 4 Type",
"standard": "-standard",
"analog": "-analog",
"negcon": "-negcon",
"Enable Vibration": "-Enable Vibration",
"Enable interlacing mode(s)": "-Enable interlacing mode(s)",
"Enhanced resolution (slow)": "-Enhanced resolution (slow)",
"Enhanced resolution speed hack": "-Enhanced resolution speed hack",
"Aspect ratio": "-Aspect ratio",
"CPU overclock": "-CPU overclock",
"Force Neo Geo mode": "-Force Neo Geo mode",
"Diagnostic Input": "-Diagnostic Input",
"download": "-download",
"keep in browser": "-keep in browser",
"Webassembly support is not detected in this browser": "-Webassembly support is not detected in this browser",
"Please upgrade your browser to the latest version": "-Please upgrade your browser to the latest version",
"Missing mame config": "-Missing mame config",
"Stop Screen Recording": "-Stop Screen Recording",
"Start Screen Recording": "-Start Screen Recording",
"Take Screenshot": "-Take Screenshot",
"Quick Save": "-Quick Save",
"Quick Load": "-Quick Load"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,198 @@
{
"nes": {
"version": "24",
"netplay": 1,
"old": { "wasm": 1, "asmjs": 1 },
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"snes": {
"version": "21",
"netplay": 1,
"old": { "wasm": 1, "asmjs": 1 },
"state": 1,
"asmjs": 0,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"pce": {
"version": "1",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"ngp": {
"version": "2",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"ws": {
"version": "1",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"vb": {
"version": "7",
"netplay": 0,
"old": { "wasm": 1, "asmjs": 1 },
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"atari2600": {
"version": "1",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"atari5200": {
"version": "4",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 0
},
"a7800": {
"version": "4",
"netplay": 0,
"state": 0,
"asmjs": 1,
"wasm": 0,
"newCores": 0,
"oldCores": 1
},
"atari7800": {
"version": "4",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 0,
"newCores": 0,
"oldCores": 1
},
"lynx": {
"version": "1",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"jaguar": {
"version": "1",
"netplay": 0,
"state": 0,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"gb": {
"version": "12",
"netplay": 0,
"state": 1,
"old": { "wasm": 0, "asmjs": 1 },
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"gbc": {
"version": "4",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 0,
"newCores": 0,
"oldCores": 1
},
"gba": {
"version": "10",
"netplay": 0,
"state": 1,
"old": { "wasm": 0, "asmjs": 1 },
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"segaGG": {
"version": "9",
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"segaMD": {
"version": "9",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"segaMS": {
"version": "9",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
},
"n64": {
"version": "13",
"netplay": 1,
"state": 1,
"asmjs": 0,
"old": { "wasm": 0, "asmjs": 1 },
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"nds": {
"version": "16",
"old": { "wasm": 1, "asmjs": 1 },
"netplay": 0,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 1,
"oldCores": 1
},
"sega32x": {
"version": "2",
"netplay": 1,
"state": 1,
"asmjs": 1,
"wasm": 1,
"newCores": 0,
"oldCores": 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 813 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,3 +0,0 @@
[InternetShortcut]
BaseURL=Byuu
Comment=NES/SNES/Sega Genesis Emulator

View File

@ -0,0 +1,3 @@
[InternetShortcut]
BaseURL=Emulator
Comment=Game Engines Emulator

View File

@ -1727,13 +1727,6 @@ byte-data@18.1.1, byte-data@^18.0.3:
ieee754-buffer "^2.0.0"
utf8-buffer "^1.0.0"
byuu@^0.16.0:
version "0.16.0"
resolved "https://registry.yarnpkg.com/byuu/-/byuu-0.16.0.tgz#25da9491b0d5ba8fd1c509c2324175e132684422"
integrity sha512-GMjHelmom4JUCxURIATdrdQNqLu8UEvLhDvzJ6d7uFK1vdi1G6DQtsrjnRQ8R2XE/NqB16Tjv1unNulwk71Y0A==
dependencies:
eventemitter3 "^4.0.0"
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
@ -2738,11 +2731,6 @@ event-target-shim@^5.0.0:
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
execa@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"