Compare commits

...

36 Commits
v4.2.3 ... main

Author SHA1 Message Date
Ethan O'Brien
50cb990a87
Fix nightly folder 2026-02-02 12:15:37 -06:00
Ethan O'Brien
b440392a49
Update dependencies and fix minify script 2026-01-03 18:58:17 -06:00
Ethan O'Brien
ae9cd11583 Add intv 2026-01-03 18:44:29 -06:00
Zen P.
780ad31d3d
fix(deps): update @node-minify packages to v10.1.1 (#1150)
Fixes high severity vulnerability in glob (CVE via @node-minify/core).

Updates:
- @node-minify/core: ^9.0.2 -> ^10.1.1
- @node-minify/clean-css: ^9.0.1 -> ^10.1.1
- @node-minify/terser: ^9.0.1 -> ^10.1.1

The glob vulnerability (GHSA-5j98-mcp5-4vw2) allowed command injection
via -c/--cmd flag. @node-minify v10.x removes glob as a dependency,
eliminating this attack vector.

Co-authored-by: Zenpower <dev@zenpower.at>
2026-01-03 15:31:55 -06:00
Mikhail Vazhnov
5680535946
Fix Sega Genesis control scheme (#1124) (#1125) 2025-10-30 20:14:23 -05:00
298A-E9E3
cf8e15ba9b
Added automatic core detection for Sega Mega Drive games (#1123) 2025-10-30 20:13:57 -05:00
Joe Thundercheeks
dfe9498bcd
Fix Issue #1039 (Save state text is inconsistent) (#1116)
* fix psx control mapping showing defaults

* fix psx mappings being incorrect

* fix psx thingy

* Fix Issue #1039

* Add files via upload
2025-10-20 16:07:46 -05:00
Joe Thundercheeks
5fdaaff215
Fix Issue #1112 (PSX Control Labels Are Incorrect) (#1115)
* fix psx control mapping showing defaults

* fix psx mappings being incorrect

* fix psx thingy
2025-10-20 07:03:50 -05:00
Ethan O'Brien
8c750dde40
Add beta bootup batch file 2025-10-19 19:40:38 -05:00
Ethan O'Brien
18e3a4c3a1
Redo start name detection 2025-10-19 17:19:46 -05:00
Ethan O'Brien
91e8d6bb31
Add bsnes/genesisplusgxwide 2025-10-19 16:49:58 -05:00
duanyu5871
c0480f888d
beforeunload event listener update (#1107)
* beforeunload update

* Rename to EJS_disableAutoUnload

* Remove value from index.html since undefined is a falsy value

---------

Co-authored-by: Ethan O'Brien <ethan.a.obrien@gmail.com>
Co-authored-by: Ethan O'Brien <77750390+ethanaobrien@users.noreply.github.com>
2025-10-15 20:50:09 -05:00
298A-E9E3
54d7dfbc1f
Improve ROM loading UX (#1105)
Make cores that require threads only available if threads are enabled
Make ROMs whose extensions are the name of a core use that core
2025-10-13 18:00:18 -05:00
ぱるん
8184ba800b
Change some of the contents of ja.json (#1102) 2025-10-06 19:58:39 -05:00
cryptonaus
8eab8f6936
Support a fixed save flushing interval (#1095)
Co-authored-by: cryptonaus <cryptonaus>
2025-09-18 08:09:07 -05:00
cryptonaus
ca6c0a9870
Add event for when a game save is updated (#1094)
* Add event for when a game save is updated

* Replace SHA-1 with Cyrb53

---------

Co-authored-by: cryptonaus <cryptonaus>
2025-09-18 08:08:45 -05:00
milktoastrat
21726dc5bc
Add/Update SVG logos (#1078)
* Add/Update SVG logos

* Rename emulatorjs-logo.svg to logo.svg

* Rename Logo.svg to old-Logo.svg

* Rename logo.svg to Logo.svg

* Update Logo.svg

* Update Logo.svg (slight color correction)

* Update emulatorjs-logo-and-type.svg (slight color correction)

* Update Logo.svg

* Update Logo.svg

* Add newline

---------

Co-authored-by: Ethan O'Brien <77750390+ethanaobrien@users.noreply.github.com>
2025-09-16 23:01:33 -05:00
lxyongit
5a6062355e
fix loadExternalFilesFixed a bug in the loadExternalFiles function by updating the writeFile call to wrap res.data in new Uint8Array. This ensures proper handling of binary or buffer data, resolving type-related errors during file writing. (#1097) 2025-09-16 23:00:02 -05:00
Michael Green
ad9586d266
Fix screenshot return in EJS_onSaveState (#1092)
* Fixed bug where a screenshot wasn't returned using EJS_onSaveState

* Refactor takeScreenshot method to return a promise with screenshot data and format; update input element in HTML for better accessibility.
2025-09-16 08:14:01 -05:00
Allan Niles
ce7472d264
test workflows 2025-08-30 18:57:36 -06:00
Allan Niles
ceeecf209a
Remove Matrix server invitation
Removed Matrix server invitation from README.
2025-08-28 21:34:34 -06:00
Ethan O'Brien
7197fc9c73 Network errors should be thrown 2025-08-27 11:47:12 -05:00
S-Coding
23337cf2db
Added netplay over WebRTC (#1053)
* Added netplay over WebRTC

* feat(netplay): Implement WebRTC and address PR feedback

* Prevent emulator loop from running on clients

* fixed formatting and changed IceServers to ICEServers

* refactor: Update loader.js

* Refactor: Overhaul netplay for better 4-player support and use config encapsulation

* Cleanup

* Cleanup

* Add newline

* Fixed message focus, added joined and left messages, hid unnecessary buttons

* Cleaned up functions bind.this, netplay button reorganization, number of players selector fix

* Added TURN server detection and warning

* cleanup

---------

Co-authored-by: S-Coding23 <>
Co-authored-by: Ethan O'Brien <ethan.a.obrien@gmail.com>
2025-08-23 21:58:00 -06:00
daguile
e4feb3c6ec
Improve multi-disc handling for dosbox-pure (#1064)
* do not extract zip file for dosbox

* Added DOSBOX as an option to index.html

* remove second initialization

* let the website decide if rom needs to be extracted

---------

Co-authored-by: Michael Green <84688932+michael-j-green@users.noreply.github.com>
2025-08-20 18:39:27 -05:00
daguile
a0f4db7610
fix silly error (#1063) 2025-08-18 08:09:06 -05:00
Georges-Antoine Assi
b5a719b846
Add jsdoc comments to compression.js (#1062)
* Add jsdoc to compression

* undo formatting
2025-08-17 15:22:23 -05:00
daguile
5bf17873d1
handle subfolders in path (#1059) 2025-08-16 12:40:23 -05:00
ぱる
55fbd5eeae
Update ja.json (#1058) 2025-08-15 20:49:10 -05:00
Ethan O'Brien
756990bdd1
Redo saves 2025-08-07 09:09:26 -05:00
Michael Green
0f9954a976
Fix for context menu (#1045)
* Fix for context menu

* Formatting fix

* Refined EJS_browserMode

* Moved browserMode from loader.js into emulator.js

* Revert loader.js to original

* Change single quotes to double quotes

* Removal of EJS_browserMode from emulator.js

* Show desktop mode messages only if debug is true.

* Block changes to all but the visible property of the contextMenu
2025-07-12 20:32:41 -06:00
uzucore
4c161abaf2
Update ko.json (#1044)
* Update ko.json

Bug fixes and translations added.

* 추가수정
2025-07-07 20:47:14 -05:00
Allan Niles
2052d68f84
Language Revamp (#1036)
* fix translations

* fix BCP 47 tags

* fix Credits

* auto lang

* missing logic

* clean up

* remove semicolon
2025-07-06 22:12:30 -06:00
Michael Green
e77610e890
Fix for broken custom buttons (#1042)
* Fix for broken custom buttons

* Removed non-standard formatting

* Removed non-standard formatting

* Removed non-standard formatting
2025-07-06 22:02:59 -05:00
t3chnob0y
8a7088a156
Update af-FR.json (#1043)
* Update af-FR.json

* Update af-FR.json
2025-07-06 19:43:50 -05:00
Allan Niles
820a9fa962
fix adding newlines after updating dependencies 2025-07-06 18:11:22 -06:00
Allan Niles
6161d7f140
Update Project Scripts 2025-07-06 17:41:13 -06:00
41 changed files with 6667 additions and 5173 deletions

View File

@ -15,7 +15,7 @@ jobs:
- name: Set Permissions
run: |
cd /mnt/HDD/public
chmod -R 755 .EmulatorJS/
chmod -R 775 .EmulatorJS/
- name: Update Latest
run: |
cd /mnt/HDD/public/.EmulatorJS/
@ -31,8 +31,12 @@ jobs:
run: |
cd /mnt/HDD/public/.EmulatorJS/data/
zip emulator.min.zip emulator.min.js emulator.min.css
- name: Copy to nightly folder
run: |
cd /mnt/HDD/public/
rsync -auv --exclude .EmulatorJS/data/cores/ .EmulatorJS/ nightly/
- name: Clean Up Minify
run: |
cd /mnt/HDD/public/.EmulatorJS/
rm -f "minify/package-lock.json"
rm -rf "minify/node_modules/"
rm -rf "minify/node_modules/" "./node_modules"

View File

@ -50,7 +50,7 @@ jobs:
- name: Set Permissions
run: |
cd /mnt/HDD/public
chmod -R 755 stable/
chmod -R 775 stable/
- name: Update Stable Cores
run: |
rsync -a --delete /mnt/HDD/public/stable/data/cores/ /mnt/HDD/public/.EmulatorJS/data/cores/

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ data/cores/*
.vscode/*
*.tgz
dist/
jsdoc/

View File

@ -13,3 +13,4 @@ data/cores/*
minify/
.npmignore
.gitignore
roms/

View File

@ -12,6 +12,30 @@ Donate to: [EmulatorJS](https://www.patreon.com/EmulatorJS)
Donate to: [libretro](https://retroarch.com/index.php?page=donate)
## Project Scripts
The project has several scripts that can be used to help with updating and deploying the project.
### Build Script
Runs the build script, which will compresses the project in 7z and zip output in dist/ folder. Note: Make sure you have the compiled cores in the `data/cores` folder before running this script.
```bash
npm run build
```
### Update Script
Runs the update script, which updates dependencies and can change version number of project. It also will update the list of contributors.
```bash
npm run update # Just updates contributors list
npm run update -- --ejs_v=4.3.1 # Updates contributors list and sets version to 4.3.1
npm run update -- --deps=true # Updates contributors list and updates dependencies
npm run update -- --dev=true # Updates contributors list and enables dev mode
npm run update -- --dev=false # Updates contributors list and disables dev mode
```
## Attention Visual Studio Code Users
By default Visual Studio Code will apply formatting that is not consistent with the standard formatting used by this project.

View File

@ -22,10 +22,6 @@ Join our Discord server:
[![Join our Discord server!](https://invidget.switchblade.xyz/6akryGkETU)](https://discord.gg/6akryGkETU)
Or the Matrix server (#emulatorjs:matrix.emulatorjs.org):
<a href="https://matrix.to/#/#emulatorjs:matrix.emulatorjs.org" rel="noopener" target="_blank"><img src="https://matrix.to/img/matrix-badge.svg" alt="Chat on Matrix"></a>
</div>
<br>

View File

@ -19,4 +19,3 @@ To install a specific core, run the following command:
```bash
npm install @emulatorjs/core-<core-name>
```

View File

@ -22,4 +22,3 @@ To install all cores, run the following command:
```bash
npm install @emulatorjs/cores
```

View File

@ -219,6 +219,13 @@
.ejs_canvas {
width: 100%;
height: 100%;
z-index: 1;
position: absolute;
top: 0;
left: 0;
transform: none;
object-fit: contain;
object-position: top;
}
.ejs_canvas_parent {
@ -226,6 +233,26 @@
height: 100%;
}
.netplay-hidden {
display: none !important;
}
.option-enabled {
color: inherit;
opacity: 1;
}
.ejs_netplay_warning {
padding: 10px;
margin-bottom: 15px;
text-align: center;
color: black !important;
background-color: rgba(255, 165, 0, 0.8);
border: 1px solid orange;
border-radius: 5px;
font-size: 0.9em;
}
.ejs_context_menu {
position: absolute;
display: none;
@ -1536,6 +1563,17 @@
fill: currentColor;
}
.ejs-vgamepad-active {
z-index: 1000;
position: absolute;
pointer-events: auto;
width: 100%;
}
.ejs-canvas-no-pointer {
pointer-events: none;
}
.ejs_netplay_header {
margin-top: .5rem;
margin-bottom: .5rem;

View File

@ -104,6 +104,7 @@
config.gamePatchUrl = window.EJS_gamePatchUrl;
config.gameParentUrl = window.EJS_gameParentUrl;
config.netplayUrl = window.EJS_netplayServer;
config.netplayICEServers = window.EJS_netplayICEServers;
config.gameId = window.EJS_gameID;
config.backgroundImg = window.EJS_backgroundImage;
config.backgroundBlur = window.EJS_backgroundBlur;
@ -115,6 +116,7 @@
config.softLoad = window.EJS_softLoad;
config.capture = window.EJS_screenCapture;
config.externalFiles = window.EJS_externalFiles;
config.dontExtractRom = window.EJS_dontExtractRom;
config.dontExtractBIOS = window.EJS_dontExtractBIOS;
config.disableDatabases = window.EJS_disableDatabases;
config.disableLocalStorage = window.EJS_disableLocalStorage;
@ -122,26 +124,62 @@
config.noAutoFocus = window.EJS_noAutoFocus;
config.videoRotation = window.EJS_videoRotation;
config.hideSettings = window.EJS_hideSettings;
config.browserMode = window.EJS_browserMode;
config.shaders = Object.assign({}, window.EJS_SHADERS, window.EJS_shaders ? window.EJS_shaders : {});
config.fixedSaveInterval = window.EJS_fixedSaveInterval;
config.disableAutoUnload = window.EJS_disableAutoUnload;
config.disableBatchBootup = window.EJS_disableBatchBootup;
let systemLang;
try {
systemLang = Intl.DateTimeFormat().resolvedOptions().locale;
} catch(e) {} //Ignore
if ((typeof window.EJS_language === "string" && window.EJS_language !== "en-US") || (systemLang && window.EJS_disableAutoLang !== false)) {
const defaultLangs = ["en", "en-US"];
const isDefaultLang = (lang) => defaultLangs.includes(lang);
if ((typeof window.EJS_language === "string" && !isDefaultLang(window.EJS_language)) || (systemLang && window.EJS_disableAutoLang !== false)) {
const language = window.EJS_language || systemLang;
const autoLang = !window.EJS_language && typeof systemLang === "string";
try {
let path;
let languagePath;
let fallbackPath = false;
console.log("Loading language", language);
if ("undefined" != typeof EJS_paths && typeof EJS_paths[language] === "string") {
path = EJS_paths[language];
languagePath = EJS_paths[language];
} else {
path = scriptPath + "localization/" + language + ".json";
languagePath = scriptPath + "localization/" + language + ".json";
if (language.includes("-") || language.includes("_")) {
fallbackPath = scriptPath + "localization/" + language.split(/[-_]/)[0] + ".json";
}
}
config.language = language;
config.langJson = JSON.parse(await (await fetch(path)).text());
let langJson = {};
let missingLang = false;
if (!isDefaultLang(language)) {
if (autoLang) {
try {
let languageJson = await fetch(languagePath);
if (!languageJson.ok) throw new Error(`Missing language file: ${languageJson.status}`);
langJson = JSON.parse(await languageJson.text());
if (fallbackPath) {
let fallbackJson = await fetch(fallbackPath);
missingLang = !fallbackJson.ok;
if (!fallbackJson.ok) throw new Error(`Missing language file: ${fallbackJson.status}`);
langJson = { ...JSON.parse(await fallbackJson.text()), ...langJson };
}
} catch(e) {
config.language = language.split(/[-_]/)[0];
console.warn("Failed to load language:", language + ",", "trying default language:", config.language);
if (!missingLang) {
langJson = JSON.parse(await (await fetch(fallbackPath)).text());
}
}
} else {
langJson = JSON.parse(await (await fetch(languagePath)).text());
}
config.langJson = langJson;
}
} catch(e) {
console.log("Missing language", language, "!!");
console.log("Missing language:", language, "!!");
delete config.language;
delete config.langJson;
}
@ -167,4 +205,8 @@
if (typeof window.EJS_onSaveSave === "function") {
window.EJS_emulator.on("saveSave", window.EJS_onSaveSave);
}
if (typeof window.EJS_onSaveUpdate === "function") {
window.EJS_emulator.on("saveUpdate", window.EJS_onSaveUpdate);
window.EJS_emulator.enableSaveUpdateEvent();
}
})();

View File

@ -2,24 +2,25 @@
Supported languages
`en-US` - English US<br>
`pt-BR` - Portuguese<br>
`es-ES` - Spanish<br>
`el-GR` - Greek<br>
`ja-JA` - Japanese<br>
`zh-CN` - Chinese<br>
`hi-HI` - Hindi<br>
`ar-AR` - Arabic<br>
`jv-JV` - Javanese<br>
`ben-BEN` - Bengali<br>
`ru-RU` - Russian<br>
`de-GER` - German<br>
`ko-KO` - Korean<br>
`af-FR` - French<br>
`it-IT` - Italian<br>
`tr-Tr` - Turkish<br>
`fa-AF` - Persian<br>
`ro-RO` - Romanian<br>
`en.json`: `en-US` - English (US)<br>
`pt.json`: `pt-BR` - Portuguese (Brazil)<br>
`es.json`: `es-419` - Spanish (Latin America)<br>
`el.json`: `el-GR` - Greek (Modern Greek)<br>
`ja.json`: `ja-JP` - Japanese (Japan)<br>
`zh.json`: `zh-CN` - Chinese (Simplified)<br>
`hi.json`: `hi-IN` - Hindi (India)<br>
`ar.json`: `ar-SA` - Arabic (Saudi Arabia)<br>
`jv.json`: `jv-ID` - Javanese (Indonesia)<br>
`bn.json`: `bn-BD` - Bengali (Bangladesh)<br>
`ru.json`: `ru-RU` - Russian (Russia)<br>
`de.json`: `de-DE` - German (Germany)<br>
`ko.json`: `ko-KR` - Korean (South Korea)<br>
`fr.json`: `fr-FR` - French (France)<br>
`it.json`: `it-IT` - Italian (Italy)<br>
`tr.json`: `tr-TR` - Turkish (Turkey)<br>
`fa.json`: `fa-AF` - Persian (Afghanistan)<br>
`ro.json`: `ro-RO` - Romanian (Romania)<br>
`vi.json`: `vi-VN` - Vietnamese (Vietnam)<br>
default: `en-US`
@ -33,18 +34,18 @@ If the language file is not found or there was an error fetching the file, the e
## Credits
Translated for `es-ES` originally by [@cesarcristianodeoliveira](https://github.com/cesarcristianodeoliveira) and updated by [@angelmarfil](https://github.com/angelmarfil) <br>
Translated for `es-419` originally by [@cesarcristianodeoliveira](https://github.com/cesarcristianodeoliveira) and updated by [@angelmarfil](https://github.com/angelmarfil) <br>
Translated for `el-GR` by [@imneckro](https://github.com/imneckro) <br>
Translated for `pt-BR` by [@zmarteline](https://github.com/zmarteline)<br>
Translated for `zh-CN` by [@eric183](https://github.com/eric183)<br>
Translated for `pt-BR` by [@zmarteline](https://github.com/zmarteline) <br>
Translated for `it-IT` by [@IvanMazzoli](https://github.com/IvanMazzoli) <br>
Translated for `tr-Tr` by [@iGoodie](https://github.com/iGoodie) <br>
Translated for `tr-TR` by [@iGoodie](https://github.com/iGoodie) <br>
Translated for `fa-AF` by [@rezamohdev](https://github.com/rezamohdev) <br>
Translated for `af-FR` by [@t3chnob0y](https://github.com/t3chnob0y) <br>
Translated for `fr-FR` by [@t3chnob0y](https://github.com/t3chnob0y) <br>
Translated for `ro-RO` by [@jurcaalexandrucristian](https://github.com/jurcaalexandrucristian) <br>
Translated for `ja-JA` by [@noel-forester](https://github.com/noel-forester) <br>
Translated for `hi-HI`, `ar-AR`, `jv-JV`, `ben-BEN`, `ru-RU`, `de-GER`, `ko-KO` by [@allancoding](https://github.com/allancoding), using a translate application <br>
Translated for `ja-JP` by [@noel-forester](https://github.com/noel-forester) <br>
Translated for `vi-VN` by [@TimKieu](https://github.com/TimKieu) <br>
Translated for `hi-IN`, `ar-SA`, `jv-iD`, `bn-BD`, `ru-RU`, `de-DE`, `ko-KR` by [@allancoding](https://github.com/allancoding), using a translate application <br>
## Contributing
@ -52,7 +53,9 @@ To contribute, please download the default `en-US.json` language file to use as
The EmulatorJS team will review and add your changes.
The `retroarch.json` are all the setting names for the menu. They will default to english if not found. You can set `EJS_settingsLanguage` to `true` to see the missing retroarch settings names for the current language. You can translate them and add the to the language file.
As of version `4.2.2` it will default to the system language.
The `retroarch.json` are all the setting names for the menu. You can set `EJS_settingsLanguage` to `true` to see the missing retroarch settings names for the current language. You can translate them and add the to the language file.
The control mapping translations for controllers are diffrent for each controller. They will need to be added to the language file if they are not in the default `en-US.json` file.

View File

@ -99,8 +99,8 @@
"Press Keyboard": "اضغط على لوحة المفاتيح",
"INSERT COIN": "إدراج عملة",
"Remove": "يزيل",
"SAVE LOADED FROM BROWSER": "وفر محملًا من المتصفح",
"SAVE SAVED TO BROWSER": "تم الحفظ في المتصفح",
"LOADED STATE FROM BROWSER": "حالة تحميل من المتصفح",
"SAVED STATE TO BROWSER": "الحالة المحفوظة في المتصفح",
"Join the discord": "انضم إلى الفتنة",
"View on GitHub": "عرض على جيثب",
"Failed to start game": "فشل بدء اللعبة",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "কীবোর্ড টিপুন",
"INSERT COIN": "মুদ্রা প্রবেশ করান",
"Remove": "অপসারণ",
"SAVE LOADED FROM BROWSER": "ব্রাউজার থেকে লোড সংরক্ষণ করুন",
"SAVE SAVED TO BROWSER": "ব্রাউজারে সংরক্ষণ করুন",
"LOADED STATE FROM BROWSER": "ব্রাউজার থেকে লোড করা অবস্থা",
"SAVED STATE TO BROWSER": "রাষ্ট্র ব্রাউজারে সংরক্ষিত হয়",
"Join the discord": "বিরোধে যোগ দিন",
"View on GitHub": "GitHub এ দেখুন",
"Failed to start game": "খেলা শুরু করতে ব্যর্থ",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "Taste drücken",
"INSERT COIN": "MÜNZE EINWERFEN",
"Remove": "Entfernen",
"SAVE LOADED FROM BROWSER": "SPEICHERSTAND VOM BROWSER GELADEN",
"SAVE SAVED TO BROWSER": "SPEICHERSTAND IM BROWSER GESPEICHERT",
"LOADED STATE FROM BROWSER": "GELADENER STATUS VOM BROWSER",
"SAVED STATE TO BROWSER": "STATUS IM BROWSER GESPEICHERT",
"Join the discord": "Treten Sie dem Discord bei",
"View on GitHub": "Auf GitHub ansehen",
"Failed to start game": "Das Spiel konnte nicht gestartet werden",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "Πατήστε Πληκτρολόγιο",
"INSERT COIN": "ΕΙΣΑΓΕΤΕ ΝΟΜΙΣΜΑ",
"Remove": "Αφαιρώ",
"SAVE LOADED FROM BROWSER": "ΑΠΟΘΗΚΕΥΣΗ ΦΟΡΤΩΜΕΝΟΥ ΑΠΟ ΤΟ BROWSER",
"SAVE SAVED TO BROWSER": "ΑΠΟΘΗΚΕΥΣΗ ΑΠΟΘΗΚΕΥΤΗΚΕ ΣΤΟ BROWSER",
"LOADED STATE FROM BROWSER": "ΦΟΡΤΩΘΗΚΕ ΚΑΤΑΣΤΑΣΗ ΑΠΟ ΤΟ BROWSER",
"SAVED STATE TO BROWSER": "ΑΠΟΘΗΚΕΥΤΗΚΕ ΚΑΤΑΣΤΑΣΗ ΣΤΟ BROWSER",
"Join the discord": "Συμμετάσχετε στη διχόνοια",
"View on GitHub": "Προβολή στο GitHub",
"Failed to start game": "Απέτυχε η έναρξη του παιχνιδιού",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "Press Keyboard",
"INSERT COIN": "INSERT COIN",
"Remove": "Remove",
"SAVE LOADED FROM BROWSER": "SAVE LOADED FROM BROWSER",
"SAVE SAVED TO BROWSER": "SAVE SAVED TO BROWSER",
"LOADED STATE FROM BROWSER": "LOADED STATE FROM BROWSER",
"SAVED STATE TO BROWSER": "SAVED STATE TO BROWSER",
"Join the discord": "Join the discord",
"View on GitHub": "View on GitHub",
"Failed to start game": "Failed to start game",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "Presionar Teclado",
"INSERT COIN": "INSERTE MONEDA",
"Remove": "Eliminar",
"SAVE LOADED FROM BROWSER": "GUARDAR CARGADO DESDE EL NAVEGADOR",
"SAVE SAVED TO BROWSER": "GUARDAR GUARDADO EN EL NAVEGADOR",
"LOADED STATE FROM BROWSER": "ESTADO CARGADO DESDE EL NAVEGADOR",
"SAVED STATE TO BROWSER": "ESTADO GUARDADO EN EL NAVEGADOR",
"Join the discord": "Únete al Discord",
"View on GitHub": "Ver en GitHub",
"Failed to start game": "Error al iniciar el juego",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "صفحه کلید را فشار دهید",
"INSERT COIN": "سکه درج کنید",
"Remove": "حذف کردن",
"SAVE LOADED FROM BROWSER": "ذخیره بارگذاری شده از مرورگر",
"SAVE SAVED TO BROWSER": "ذخیره در مرورگر ذخیره شد",
"LOADED STATE FROM BROWSER": "وضعیت بارگیری شده از مرورگر",
"SAVED STATE TO BROWSER": "وضعیت در مرورگر ذخیره شد",
"Join the discord": "به دیسکورد discord بپیوندید",
"View on GitHub": "در GitHub مشاهده کنید",
"Failed to start game": "شروع بازی ناموفق بود",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "Appuyez sur le clavier",
"INSERT COIN": "INSÉRER UNE PIÈCE",
"Remove": "Retirer",
"SAVE LOADED FROM BROWSER": "SAUVEGARDE CHARGÉE À PARTIR DU NAVIGATEUR",
"SAVE SAVED TO BROWSER": "SAUVEGARDE ENREGISTRÉE DANS LE NAVIGATEUR",
"LOADED STATE FROM BROWSER": "ÉTAT CHARGÉ À PARTIR DU NAVIGATEUR",
"SAVED STATE TO BROWSER": "ÉTAT ENREGISTRÉ DANS LE NAVIGATEUR",
"Join the discord": "Rejoindre le serveur Discord",
"View on GitHub": "Afficher sur GitHub",
"Failed to start game": "Échec au démarrage du jeu",
@ -149,26 +149,26 @@
"L": "L",
"R": "R",
"Z": "Z",
"STICK UP": "STICK HAUT",
"STICK DOWN": "STICK BAS",
"STICK LEFT": "STICK GAUCHE",
"STICK RIGHT": "STICK DROITE",
"C-PAD UP": "C-PAD HAUT",
"C-PAD DOWN": "C-PAD BAS",
"C-PAD LEFT": "C-PAD GAUCHE",
"C-PAD RIGHT": "C-PAD DROITE",
"STICK UP": "MANCHE HAUT",
"STICK DOWN": "MANCHE BAS",
"STICK LEFT": "MANCHE GAUCHE",
"STICK RIGHT": "MANCHE DROITE",
"C-PAD UP": "CROIX HAUT",
"C-PAD DOWN": "CROIX BAS",
"C-PAD LEFT": "CROIX GAUCHE",
"C-PAD RIGHT": "CROIX DROITE",
"MICROPHONE": "MICROPHONE",
"BUTTON 1 / START": "BOUTON 1 / START",
"BUTTON 2": "BOUTON 2",
"BUTTON": "BOUTON",
"LEFT D-PAD UP": "D-PAD GAUCHE HAUT",
"LEFT D-PAD DOWN": "D-PAD GAUCHE BAS",
"LEFT D-PAD LEFT": "D-PAD GAUCHE GAUCHE",
"LEFT D-PAD RIGHT": "D-PAD GAUCHE DROITE",
"RIGHT D-PAD UP": "D-PAD DROIT HAUT",
"RIGHT D-PAD DOWN": "D-PAD DROIT BAS",
"RIGHT D-PAD LEFT": "D-PAD DROIT GAUCHE",
"RIGHT D-PAD RIGHT": "D-PAD DROIT DROITE",
"LEFT D-PAD UP": "CROIX G HAUT",
"LEFT D-PAD DOWN": "CROIX G BAS",
"LEFT D-PAD LEFT": "CROIX G GAUCHE",
"LEFT D-PAD RIGHT": "CROIX G DROITE",
"RIGHT D-PAD UP": "CROIX D HAUT",
"RIGHT D-PAD DOWN": "CROIX D BAS",
"RIGHT D-PAD LEFT": "CROIX D GAUCHE",
"RIGHT D-PAD RIGHT": "CROIX D DROITE",
"C": "C",
"MODE": "MODE",
"FIRE": "FIRE",
@ -187,14 +187,14 @@
"R2": "R2",
"L3": "L3",
"R3": "R3",
"L STICK UP": "STICK G HAUT",
"L STICK DOWN": "STICK G BAS",
"L STICK LEFT": "STICK G GAUCHE",
"L STICK RIGHT": "STICK G DROITE",
"R STICK UP": "STICK D HAUT",
"R STICK DOWN": "STICK D BAS",
"R STICK LEFT": "STICK D GAUCHE",
"R STICK RIGHT": "STICK D DROITE",
"L STICK UP": "MANCHE G HAUT",
"L STICK DOWN": "MANCHE G BAS",
"L STICK LEFT": "MANCHE G GAUCHE",
"L STICK RIGHT": "MANCHE G DROITE",
"R STICK UP": "MANCHE D HAUT",
"R STICK DOWN": "MANCHE D BAS",
"R STICK LEFT": "MANCHE D GAUCHE",
"R STICK RIGHT": "MANCHE D DROITE",
"Start": "START",
"Select": "SELECT",
"Fast": "FAST",
@ -285,10 +285,10 @@
">": ">",
"/": "/",
"?": "?",
"LEFT_STICK_X": "STICK_GAUCHE_X",
"LEFT_STICK_Y": "STICK_GAUCHE_Y",
"RIGHT_STICK_X": "STICK_DROIT_X",
"RIGHT_STICK_Y": "STICK_DROIT_Y",
"LEFT_STICK_X": "MANCHE_GAUCHE_X",
"LEFT_STICK_Y": "MANCHE_GAUCHE_Y",
"RIGHT_STICK_X": "MANCHE_DROIT_X",
"RIGHT_STICK_Y": "MANCHE_DROIT_Y",
"LEFT_TRIGGER": "GACHETTE_GAUCHE",
"RIGHT_TRIGGER": "GACHETTE_DROITE",
"A_BUTTON": "BOUTON_A",
@ -301,12 +301,12 @@
"R1_BUTTON": "BOUTON_R1",
"L2_BUTTON": "BOUTON_L2",
"R2_BUTTON": "BOUTON_R2",
"LEFT_THUMB_BUTTON": "BOUTON_L3",
"RIGHT_THUMB_BUTTON": "BOUTON_R3",
"DPAD_UP": "DPAD_HAUT",
"DPAD_DOWN": "DPAD_BAS",
"DPAD_LEFT": "DPAD_GAUCHE",
"DPAD_RIGHT": "DPAD_DROITE",
"LEFT_THUMB_BUTTON": "BOUTON_MANCHE_GAUCHE",
"RIGHT_THUMB_BUTTON": "BOUTON_MANCHE_DROIT",
"DPAD_UP": "CROIX_HAUT",
"DPAD_DOWN": "CROIX_BAS",
"DPAD_LEFT": "CROIX_GAUCHE",
"DPAD_RIGHT": "CROIX_DROITE",
"Disks": "Disques",
"Exit EmulatorJS": "Quitter EmulatorJS",
"BUTTON_1": "BOUTON_1",
@ -317,8 +317,8 @@
"down arrow": "Flèche bas",
"left arrow": "Flèche gauche",
"right arrow": "Flèche droite",
"LEFT_TOP_SHOULDER": "SHOULDER_GAUCHE_HAUT",
"RIGHT_TOP_SHOULDER": "SHOULDER_DROITE_HAUT",
"LEFT_TOP_SHOULDER": "BOUTON_EPAULE_GAUCHE",
"RIGHT_TOP_SHOULDER": "BOUTON_EPAULE_DROITE",
"CRT beam": "CRT beam",
"CRT caligari": "CRT caligari",
"CRT lottes": "CRT lottes",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "कीबोर्ड दबाएँ",
"INSERT COIN": "सिक्का डालें",
"Remove": "निकालना",
"SAVE LOADED FROM BROWSER": "ब्राउज़र से लोड किया गया सेव करें",
"SAVE SAVED TO BROWSER": "ब्राउज़र में सहेजा गया सहेजें",
"LOADED STATE FROM BROWSER": "ब्राउज़र से लोड किया गया राज्य",
"SAVED STATE TO BROWSER": "राज्य को ब्राउज़र में सहेजा गया",
"Join the discord": "कलह में शामिल हों",
"View on GitHub": "GitHub पर देखें",
"Failed to start game": "गेम प्रारंभ करने में विफल",

View File

@ -100,8 +100,8 @@
"Press Keyboard": "Premi Tastiera",
"INSERT COIN": "INSERISCI GETTONE",
"Remove": "Rimuovi",
"SAVE LOADED FROM BROWSER": "SALVATAGGIO CARICATO DA BROWSER",
"SAVE SAVED TO BROWSER": "SALVATAGGIO SALVATO SU BROWSER",
"LOADED STATE FROM BROWSER": "STATO CARICATO DAL BROWSER",
"SAVED STATE TO BROWSER": "STATO SALVATO NEL BROWSER",
"Join the discord": "Entra nel Discord",
"View on GitHub": "Vedi su Github",
"Failed to start game": "Avvio del gioco fallito",

View File

@ -9,12 +9,12 @@
"7": "7",
"8": "8",
"9": "9",
"Restart": "再起動",
"Restart": "リセット",
"Pause": "一時停止",
"Play": "",
"Save State": "ステートセーブ",
"Load State": "ステートロード",
"Control Settings": "キーコンフィグ",
"Play": "開",
"Save State": "セーブステート",
"Load State": "ロードステート",
"Control Settings": "キー設定",
"Cheats": "チート",
"Cache Manager": "キャッシュマネージャー",
"Export Save File": "セーブデータをエクスポート",
@ -37,15 +37,15 @@
"Gamepad": "ゲームパッド",
"Keyboard": "キーボード",
"Set": "セット",
"Add Cheat": "チート追加",
"Add Cheat": "チート追加",
"Create a Room": "部屋を作成",
"Rooms": "部屋",
"Start Game": "ゲームスタート",
"Loading...": "読み込み中...",
"Download Game Core": "ゲームコアをダウンロード",
"Decompress Game Core": "ゲームコアを解凍",
"Download Game Data": "ゲームデータのダウンロード",
"Decompress Game Data": "ゲームデータを解凍",
"Download Game Core": "ゲームコアをダウンロード",
"Decompress Game Core": "ゲームコアを解凍",
"Download Game Data": "ゲームデータのダウンロード",
"Decompress Game Data": "ゲームデータを解凍",
"Shaders": "シェーダー",
"Disabled": "無効",
"2xScaleHQ": "2xスケール",
@ -57,11 +57,11 @@
"FPS": "FPS",
"show": "表示",
"hide": "非表示",
"Fast Forward Ratio": "早送り速度",
"Fast Forward Ratio": "早送り速度",
"Fast Forward": "早送り",
"Enabled": "有効",
"Save State Slot": "ステートセーブスロット",
"Save State Location": "ステートセーブ保存場所",
"Save State Slot": "セーブステートのスロット",
"Save State Location": "セーブステートの保存場所",
"Download": "ダウンロード",
"Keep in Browser": "ブラウザ内に保持",
"Auto": "自動",
@ -72,20 +72,20 @@
"4:3": "4:3",
"Low": "低",
"High": "高",
"Very High": "高",
"Very High": "高",
"None": "なし",
"Player 1": "プレイヤー1",
"Player 2": "プレイヤー2",
"Both": "両方",
"SAVED STATE TO SLOT": "状態をスロットにセーブしました",
"LOADED STATE FROM SLOT": "状態をスロットからロードしました",
"SET SAVE STATE SLOT TO": "状態保存スロットを次のように設定します",
"SAVED STATE TO SLOT": "データをセーブしました(スロット:",
"LOADED STATE FROM SLOT": "データをロードしました(スロット:",
"SET SAVE STATE SLOT TO": "保存スロットを次に設定します(スロット:",
"Network Error": "ネットワークエラー",
"Submit": "適用",
"Description": "説明",
"Code": "コード",
"Add Cheat Code": "チートコードを追加する",
"Leave Room": "部屋を退出",
"Leave Room": "部屋を退出する",
"Password": "パスワード",
"Password (optional)": "パスワード (オプション)",
"Max Players": "最大プレイヤー数",
@ -99,18 +99,18 @@
"Press Keyboard": "キーボードを押す",
"INSERT COIN": "コインを入れる",
"Remove": "削除",
"SAVE LOADED FROM BROWSER": "セーブをブラウザからロード",
"SAVE SAVED TO BROWSER": "セーブをブラウザに保存",
"Join the discord": "ディスコードに参加",
"LOADED STATE FROM BROWSER": "ブラウザからロード状態",
"SAVED STATE TO BROWSER": "状態をブラウザに保存",
"Join the discord": "Discordに参加",
"View on GitHub": "GitHub で見る",
"Failed to start game": "ゲームの開始に失敗しました",
"Download Game BIOS": "ゲームBIOSをダウンロード",
"Decompress Game BIOS": "ゲームBIOSを解凍",
"Download Game Parent": "ゲームの親をダウンロード",
"Decompress Game Parent": "ゲームの親を解凍",
"Download Game Patch": "ゲームパッチをダウンロード",
"Decompress Game Patch": "ゲームパッチを解凍",
"Download Game State": "ゲームステートのダウンロード",
"Download Game BIOS": "ゲームBIOSをダウンロード",
"Decompress Game BIOS": "ゲームBIOSを解凍",
"Download Game Parent": "ゲームの親をダウンロード",
"Decompress Game Parent": "ゲームの親を解凍",
"Download Game Patch": "ゲームパッチをダウンロード",
"Decompress Game Patch": "ゲームパッチを解凍",
"Download Game State": "ゲームステートのダウンロード",
"Check console": "コンソールを確認してください",
"Error for site owner": "サイト所有者のエラー",
"EmulatorJS": "エミュレータJS",
@ -119,12 +119,12 @@
"Quick Save": "クイックセーブ",
"Quick Load": "クイックロード",
"REWIND": "巻き戻し",
"Rewind Enabled (requires restart)": "巻き戻しが有効 (再起動が必要)",
"Rewind Enabled (requires restart)": "巻き戻しが有効 (再起動が必要です)",
"Rewind Granularity": "巻き戻し粒度",
"Slow Motion Ratio": "スローモーション比率",
"Slow Motion": "スローモーション",
"Home": "ホーム",
"EmulatorJS License": "エミュレータJSライセンス",
"EmulatorJS License": "エミュレータJSライセンス",
"RetroArch License": "RetroArch ライセンス",
"SLOW MOTION": "スローモーション",
"A": "A",
@ -222,10 +222,10 @@
"tab": "tab",
"backspace": "backspace",
"delete": "delete",
"arrowup": "矢印",
"arrowdown": "矢印",
"arrowleft": "矢印",
"arrowright": "矢印",
"arrowup": "矢印",
"arrowdown": "矢印",
"arrowleft": "矢印",
"arrowright": "矢印",
"f1": "f1",
"f2": "f2",
"f3": "f3",
@ -276,16 +276,16 @@
">": ">",
"/": "/",
"?": "?",
"LEFT_STICK_X": "左スティック_X",
"LEFT_STICK_Y": "左スティック_Y",
"RIGHT_STICK_X": "右スティック_X",
"RIGHT_STICK_Y": "右スティック_Y",
"LEFT_STICK_X": "左スティック(横)",
"LEFT_STICK_Y": "左スティック(縦)",
"RIGHT_STICK_X": "右スティック(横)",
"RIGHT_STICK_Y": "右スティック(縦)",
"LEFT_TRIGGER": "左トリガー",
"RIGHT_TRIGGER": "右トリガー",
"A_BUTTON": "A_ボタン",
"B_BUTTON": "B_ボタン",
"X_BUTTON": "X_ボタン",
"Y_BUTTON": "Y_ボタン",
"A_BUTTON": "Aボタン",
"B_BUTTON": "Bボタン",
"X_BUTTON": "Xボタン",
"Y_BUTTON": "Yボタン",
"START_BUTTON": "スタートボタン",
"SELECT_BUTTON": "セレクトボタン",
"L1_BUTTON": "L1_ボタン",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "Pencet Keyboard",
"INSERT COIN": "INSERT COIN",
"Remove": "Mbusak",
"SAVE LOADED FROM BROWSER": "Simpen dimuat saka BROWSER",
"SAVE SAVED TO BROWSER": "SAVE disimpen menyang BROWSER",
"LOADED STATE FROM BROWSER": "NEGARA YANG DIMUAT DARI BROWSER",
"SAVED STATE TO BROWSER": "NEGARA TERSIMPAN KE BROWSER",
"Join the discord": "Melu discord",
"View on GitHub": "Deleng ing GitHub",
"Failed to start game": "Gagal miwiti game",

View File

@ -12,7 +12,7 @@
"Restart": "재시작",
"Pause": "일시정지",
"Play": "플레이",
"Save State": "상태 세이브",
"Save State": "상태 저장하기",
"Load State": "상태 불러오기",
"Control Settings": "컨트롤 설정",
"Cheats": "치트",
@ -23,14 +23,14 @@
"Mute": "무음",
"Unmute": "음소거 해제",
"Settings": "설정",
"Enter Fullscreen": "전체화면",
"Enter Fullscreen": "전체화면 전환",
"Exit Fullscreen": "전체화면 종료",
"Context Menu": "컨텍스트 메뉴",
"Reset": "초기화",
"Clear": " 지우기",
"Clear": "지우기",
"Close": "닫기",
"QUICK SAVE STATE": "빠른 상태 세이브",
"QUICK LOAD STATE": "빠른 상태 러오기",
"QUICK SAVE STATE": "빠른 상태 저장하기",
"QUICK LOAD STATE": "빠른 상태 러오기",
"CHANGE STATE SLOT": "상태 슬롯 변경하기",
"FAST FORWARD": "빨리 감기",
"Player": "플레이어",
@ -65,8 +65,8 @@
"Fast Forward Ratio": "빨리 감기 비율",
"Fast Forward": "빨리 감기",
"Enabled": "활성화됨",
"Save State Slot": "상태 슬롯 세이브",
"Save State Location": "상태 세이브 위치",
"Save State Slot": "상태 저장 슬롯",
"Save State Location": "상태 저장 위치",
"Download": "다운로드",
"Keep in Browser": "브라우저에 보관하기",
"Auto": "자동",
@ -98,14 +98,14 @@
"Join": "들어가기",
"Player Name": "플레이어 이름",
"Set Player Name": "플레이어 이름 설정",
"Left Handed Mode": "왼손잡이 모드",
"Left Handed Mode": "왼손 모드",
"Virtual Gamepad": "가상 게임패드",
"Disk": "디스크",
"Press Keyboard": "키보드를 누르세요.",
"INSERT COIN": "동전을 넣으세요.",
"Remove": "제거",
"SAVE LOADED FROM BROWSER": "브라우저에서 세이브를 불러왔습니다.",
"SAVE SAVED TO BROWSER": "브라우저에 세이브가 저장되었습니가",
"LOADED STATE FROM BROWSER": "브라우저에서 로드된 상태",
"SAVED STATE TO BROWSER": "브라우저에 저장된 상태",
"Join the discord": "디스코드에 참가하기",
"View on GitHub": "GitHub에서 보기",
"Failed to start game": "게임을 시작하지 못했습니다.",
@ -122,11 +122,11 @@
"Clear All": "모두 지우기",
"Take Screenshot": "스크린 샷 찍기",
"Start screen recording": "화면 녹화 시작",
"Stop screen recording": "화면 녹화 정",
"Quick Save": "빠른 세이브",
"Stop screen recording": "화면 녹화 정",
"Quick Save": "빠른 저장하기",
"Quick Load": "빠른 불러오기",
"REWIND": "되감기",
"Rewind Enabled (requires restart)": "되감기 활성화됨 (다시 시작해야 함)",
"Rewind Enabled (requires restart)": "되감기 활성화됨 (재시작 필요함)",
"Rewind Granularity": "되감기 세분화",
"Slow Motion Ratio": "슬로우 모션 비율",
"Slow Motion": "슬로우 모션",
@ -306,7 +306,7 @@
"DPAD_UP": "DPAD_위",
"DPAD_DOWN": "DPAD_아래",
"DPAD_LEFT": "DPAD_왼쪽",
"DPAD_RIGHT": "DPAD_오른쪽"
"DPAD_RIGHT": "DPAD_오른쪽",
"Disks": "디스크",
"Exit EmulatorJS": "EmulatorJS 끝내기",
"BUTTON_1": "버튼_1",
@ -319,18 +319,54 @@
"right arrow": "화살표 키 오른쪽",
"LEFT_TOP_SHOULDER": "왼쪽 상단 숄더",
"RIGHT_TOP_SHOULDER": "오른쪽 상단 숄더",
"CRT beam": "CRT beam",
"CRT caligari": "CRT caligari",
"CRT lottes": "CRT lottes",
"CRT yeetron": "CRT yeetron",
"CRT zfast": "CRT zfast",
"CRT beam": "CRT ",
"CRT caligari": "CRT 칼리가리",
"CRT lottes": "CRT 로테스",
"CRT yeetron": "CRT 이트론",
"CRT zfast": "CRT 지패스트",
"SABR": "SABR",
"Bicubic": "쌍입방(Bicubic)",
"Mix frames": "혼합 프레임",
"Mix frames": "프레임 혼합",
"WebGL2": "WebGL2",
"Requires restart": "다시 시작해야 합니다.",
"VSync": "VSync",
"Video Rotation": "비디오 회전",
"Rewind Enabled (Requires restart)": "되감기 활성화 (재시작 필요)",
"System Save interval": "시스템 세이브 간격"
"Requires restart": "재시작 필요함",
"VSync": "수직동기화",
"Video Rotation": "화면 회전",
"System Save interval": "시스템 세이브 간격",
"Menu Bar Button": "메뉴바 버튼",
"visible": "보이기",
"hidden": "숨기기",
"Exit Emulation": "에뮬레이터 종료",
"LEFT_BOTTOM_SHOULDER": "왼쪽 하단 숄더",
"RIGHT_BOTTOM_SHOULDER": "오른쪽 하단 숄더",
"LEFT_STICK": "왼쪽 스틱",
"RIGHT_STICK": "오른쪽 스틱",
"-1": "-1",
"+1": "+1",
"Mode": "모드",
"": "",
"Core (재시작 필요함)": "코어 (재시작 필요함)",
"Rewind Enabled (재시작 필요함)": "되감기 활성화 (재시작 필요함)",
"Menubar Mouse Trigger": "메뉴바 마우스 활성화",
"Downward Movement": "아래쪽 이동",
"Movement Anywhere": "전체 영역 이동",
"Direct Keyboard Input": "키보드 직접 입력",
"Forward Alt key": "Alt 키 전달",
"Lock Mouse": "마우스 잠금",
"Are you sure you want to exit?": "정말로 종료하시겠습니까?",
"Exit": "종료",
"Cancel": "취소",
"EmulatorJS has exited": "에뮬레이터가 종료되었습니다.",
"Start Screen Recording": "화면 녹화 시작",
"Stop Screen Recording": "화면 녹화 중지",
"Screenshot Source": "스크린샷 소스",
"Screenshot Format": "스크린샷 형식",
"Screenshot Upscale": "스크린샷 업스케일",
"Screen Recording FPS": "화면 녹화 프레임율",
"Screen Recording Format": "화면 녹화 형식",
"Screen Recording Upscale": "화면 녹화 업스케일",
"Screen Recording Video Bitrate": "화면 녹화 비디오 비트레이트",
"Screen Recording Audio Bitrate": "화면 녹화 오디오 비트레이트",
"customDownload": "상태 파일 다운로드",
"customUpload": "상태 파일 업로드",
"customScreenshot": "스크린 샷 찍기"
}

View File

@ -105,8 +105,8 @@
"Press Keyboard": "Pressione uma tecla",
"INSERT COIN": "Insira uma ficha",
"Remove": "Remover",
"SAVE LOADED FROM BROWSER": "SAVE STATE CARREGADO DO BROWSER",
"SAVE SAVED TO BROWSER": "SAVE STATE ARMAZENADO NO BROWSER",
"LOADED STATE FROM BROWSER": "ESTADO CARREGADO DO NAVEGADOR",
"SAVED STATE TO BROWSER": "ESTADO SALVO NO NAVEGADOR",
"Join the discord": "Participar do discord",
"View on GitHub": "Ver no GitHub",
"Failed to start game": "Falha ao iniciar o jogo",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "Apasă Tastatură",
"INSERT COIN": "INSERT COIN",
"Remove": "Înlăturare",
"SAVE LOADED FROM BROWSER": "SAVE LOADED FROM BROWSER",
"SAVE SAVED TO BROWSER": "SAVE SAVED TO BROWSER",
"LOADED STATE FROM BROWSER": "STARE ÎNCĂRCATĂ DIN BROWSER",
"SAVED STATE TO BROWSER": "STARE SALVATĂ ÎN BROWSER",
"Join the discord": "Alăturăte pe Discord",
"View on GitHub": "Vezi în GitHub",
"Failed to start game": "Pornirea jocului a eșuat",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "Нажмите кнопку на клавиатуре",
"INSERT COIN": "ВСТАВЬТЕ МОНЕТУ",
"Remove": "Удалить",
"SAVE LOADED FROM BROWSER": "ЗАГРУЖЕНО ИЗ БРАУЗЕРА",
"SAVE SAVED TO BROWSER": "СОХРАНЕНО В БРАУЗЕРЕ",
"LOADED STATE FROM BROWSER": "ЗАГРУЖЕННОЕ СОСТОЯНИЕ ИЗ БРАУЗЕРА",
"SAVED STATE TO BROWSER": "СОХРАНЕННОЕ СОСТОЯНИЕ В БРАУЗЕРЕ",
"Join the discord": "Присоединяйтесь к discord",
"View on GitHub": "Посмотреть на GitHub",
"Failed to start game": "Не удалось запустить игру",

View File

@ -104,8 +104,8 @@
"Press Keyboard": "Klavyeye Basın",
"INSERT COIN": "JETON ATINIZ",
"Remove": "Kaldır",
"SAVE LOADED FROM BROWSER": "KAYIT TARAYICIDAN YÜKLENDİ",
"SAVE SAVED TO BROWSER": "KAYIT TARAYICIYA KAYDEDİLDİ",
"LOADED STATE FROM BROWSER": "TARAYICIDAN YÜKLENEN DURUM",
"SAVED STATE TO BROWSER": "TARAYICILARA KAYDEDİLDİ DURUM",
"Join the discord": "Discord'a katıl",
"View on GitHub": "Github'da görüntüler",
"Failed to start game": "Oyun başlatılamadı",

View File

@ -100,8 +100,8 @@
"Press Keyboard": "Bàn phím",
"INSERT COIN": "THÊM XU",
"Remove": "Loại bỏ",
"SAVE LOADED FROM BROWSER": "SAVE LOADED FROM BROWSER",
"SAVE SAVED TO BROWSER": "SAVE SAVED TO BROWSER",
"LOADED STATE FROM BROWSER": "TRẠNG THÁI ĐÃ TẢI TỪ TRÌNH DUYỆT",
"SAVED STATE TO BROWSER": "TRẠNG THÁI ĐÃ LƯU VÀO TRÌNH DUYỆT",
"Join the discord": "Tham gia thảo luận",
"View on GitHub": "Xem trên GitHub",
"Failed to start game": "Thất bại khởi động game",

View File

@ -99,8 +99,8 @@
"Press Keyboard": "按键盘",
"INSERT COIN": "投币",
"Remove": "消除",
"SAVE LOADED FROM BROWSER": "已从浏览器加载状态",
"SAVE SAVED TO BROWSER": "已将状态保存到浏览器",
"LOADED STATE FROM BROWSER": "浏览器加载状态",
"SAVED STATE TO BROWSER": "已将状态保存至浏览器",
"Join the discord": "加入discord",
"View on GitHub": "在GitHub上查看",
"Failed to start game": "无法开始游戏",

View File

@ -5,7 +5,7 @@ class EJS_GameManager {
this.FS = this.Module.FS;
this.functions = {
restart: this.Module.cwrap("system_restart", "", []),
saveStateInfo: this.Module.cwrap("save_state_info", "string", []),
//saveStateInfo: this.Module.cwrap("save_state_info", "string", []),
loadState: this.Module.cwrap("load_state", "number", ["string", "number"]),
screenshot: this.Module.cwrap("cmd_take_screenshot", "", []),
simulateInput: this.Module.cwrap("simulate_input", "null", ["number", "number", "number"]),
@ -109,7 +109,7 @@ class EJS_GameManager {
}
}
try {
this.writeFile(path, res.data);
this.writeFile(path, new Uint8Array(res.data));
} catch(e) {
if (this.EJS.debug) console.warn("Failed to write file to '" + path + "'. Make sure there are no conflicting files.");
}
@ -164,6 +164,22 @@ class EJS_GameManager {
}
return cfg;
}
writeBootupBatchFile() {
const data = `
SET BLASTER=A220 I7 D1 H5 T6
@ECHO OFF
mount A / -t floppy
SET PATH=Z:\\;A:\\
mount c /emulator/c
c:
COMMAND.COM
IF EXIST AUTORUN.BAT AUTORUN.BAT
`;
const filename = "BOOTUP.BAT";
this.FS.writeFile("/" + filename, data);
return filename;
}
initShaders() {
if (!this.EJS.config.shaders) return;
this.mkdir("/shader");
@ -185,15 +201,7 @@ class EJS_GameManager {
this.functions.restart();
}
getState() {
const state = this.functions.saveStateInfo().split("|");
if (state[2] !== "1") {
console.error(state[0]);
throw new Error(state[0]);
}
const size = parseInt(state[0]);
const dataStart = parseInt(state[1]);
const data = this.Module.HEAPU8.subarray(dataStart, dataStart + size);
return new Uint8Array(data);
return this.Module.EmulatorJSGetState();
}
loadState(state) {
try {
@ -210,7 +218,7 @@ class EJS_GameManager {
}
screenshot() {
try {
this.FS.unlink("screenshot.png");
this.FS.unlink("/screenshot.png");
} catch(e) {}
this.functions.screenshot();
return new Promise(async resolve => {

View File

@ -1,18 +1,55 @@
class EJS_COMPRESSION {
/**
* Handles compression and decompression of various archive formats (ZIP, 7Z, RAR)
* for the EmulatorJS system.
*
* This class provides functionality to detect compressed file formats and extract
* their contents using web workers for better performance.
*/
class EJSCompression {
/**
* Creates a new compression handler instance.
*
* @param {Object} EJS - The main EmulatorJS instance
*/
constructor(EJS) {
this.EJS = EJS;
}
isCompressed(data) { //https://www.garykessler.net/library/file_sigs.html
//todo. Use hex instead of numbers
if ((data[0] === 80 && data[1] === 75) && ((data[2] === 3 && data[3] === 4) || (data[2] === 5 && data[3] === 6) || (data[2] === 7 && data[3] === 8))) {
return "zip";
} else if (data[0] === 55 && data[1] === 122 && data[2] === 188 && data[3] === 175 && data[4] === 39 && data[5] === 28) {
return "7z";
} else if ((data[0] === 82 && data[1] === 97 && data[2] === 114 && data[3] === 33 && data[4] === 26 && data[5] === 7) && ((data[6] === 0) || (data[6] === 1 && data[7] == 0))) {
return "rar";
/**
* Detects if the given data represents a compressed archive format.
*
* @param {Uint8Array|ArrayBuffer} data - The binary data to analyze
* @returns {string|null} The detected compression format ('zip', '7z', 'rar') or null if not compressed
*
* @description
* Checks the file signature (magic bytes) at the beginning of the data to identify
* the compression format. Supports ZIP, 7Z, and RAR formats.
*
* @see {@link https://www.garykessler.net/library/file_sigs.html|File Signature Database}
*/
isCompressed(data) {
if ((data[0] === 0x50 && data[1] === 0x4B) && ((data[2] === 0x03 && data[3] === 0x04) || (data[2] === 0x05 && data[3] === 0x06) || (data[2] === 0x07 && data[3] === 0x08))) {
return "zip";
} else if (data[0] === 0x37 && data[1] === 0x7A && data[2] === 0xBC && data[3] === 0xAF && data[4] === 0x27 && data[5] === 0x1C) {
return "7z";
} else if ((data[0] === 0x52 && data[1] === 0x61 && data[2] === 0x72 && data[3] === 0x21 && data[4] === 0x1A && data[5] === 0x07) && ((data[6] === 0x00) || (data[6] === 0x01 && data[7] === 0x00))) {
return "rar";
}
return null;
}
return null;
}
/**
* Decompresses the given data and extracts all files.
*
* @param {Uint8Array|ArrayBuffer} data - The compressed data to extract
* @param {Function} updateMsg - Callback function for progress updates (message, isProgress)
* @param {Function} fileCbFunc - Callback function called for each extracted file (filename, fileData)
* @returns {Promise<Object>} Promise that resolves to an object mapping filenames to file data
*
* @description
* Automatically detects the compression format and delegates to the appropriate
* decompression method. If the data is not compressed, returns it as-is.
*/
decompress(data, updateMsg, fileCbFunc) {
const compressed = this.isCompressed(data.slice(0, 10));
if (compressed === null) {
@ -23,6 +60,20 @@ class EJS_COMPRESSION {
}
return this.decompressFile(compressed, data, updateMsg, fileCbFunc);
}
/**
* Retrieves the appropriate worker script for the specified compression method.
*
* @param {string} method - The compression method ('7z', 'zip', or 'rar')
* @returns {Promise<Blob>} Promise that resolves to a Blob containing the worker script
*
* @description
* Downloads the necessary worker script and WASM files for the specified compression
* method. For RAR files, also downloads the libunrar.wasm file and creates a custom
* worker script with the WASM binary embedded.
*
* @throws {Error} When network errors occur during file downloads
*/
getWorkerFile(method) {
return new Promise(async (resolve, reject) => {
let path, obj;
@ -107,6 +158,26 @@ class EJS_COMPRESSION {
}
})
}
/**
* Decompresses a file using the specified compression method.
*
* @param {string} method - The compression method ('7z', 'zip', or 'rar')
* @param {Uint8Array|ArrayBuffer} data - The compressed data to extract
* @param {Function} updateMsg - Callback function for progress updates (message, isProgress)
* @param {Function} fileCbFunc - Callback function called for each extracted file (filename, fileData)
* @returns {Promise<Object>} Promise that resolves to an object mapping filenames to file data
*
* @description
* Creates a web worker to handle the decompression process asynchronously.
* The worker communicates progress updates and extracted files back to the main thread.
*
* @example
* // Message types from worker:
* // t: 4 - Progress update (current, total, name)
* // t: 2 - File extracted (file, size, data)
* // t: 1 - Extraction complete
*/
decompressFile(method, data, updateMsg, fileCbFunc) {
return new Promise(async callback => {
const file = await this.getWorkerFile(method);
@ -139,4 +210,4 @@ class EJS_COMPRESSION {
}
}
window.EJS_COMPRESSION = EJS_COMPRESSION;
window.EJS_COMPRESSION = EJSCompression;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<defs>
<style>
.cls-1 {
fill: #0098c5;
}
.cls-2 {
fill: #0b3351;
}
.cls-3 {
fill: #28b9ec;
}
</style>
</defs>
<g>
<g>
<path class="cls-3" d="M752.22,513.65c-7.42,0-14.41-1.87-20.52-5.16-7.64-4.12-13.91-10.47-17.93-18.19-3.11-5.98-4.86-12.76-4.86-19.97,0-7.91,2.12-15.32,5.81-21.7,3.8-6.54,9.25-11.99,15.8-15.78,6.39-3.7,13.8-5.82,21.71-5.82,7.33,0,14.25,1.82,20.29,5.04-1.11-7.95-2.56-15.78-4.34-23.5-10.62-46.38-32.79-88.34-63.32-122.72-6.37-7.17-13.11-14-20.16-20.48-49.72-45.61-116-73.44-188.77-73.44s-139.05,27.83-188.75,73.44c-7.07,6.48-13.79,13.31-20.16,20.48-30.76,34.65-53.04,76.99-63.57,123.81-4.47,19.81-6.82,40.42-6.82,61.58s2.14,39.78,6.18,58.72c10.21,47.77,32.65,91.01,63.87,126.29,6.34,7.17,13.04,14,20.08,20.48,49.74,45.84,116.19,73.82,189.16,73.82s139.42-27.98,189.18-73.82c7.04-6.48,13.73-13.31,20.08-20.48,30.77-34.78,53.02-77.29,63.43-124.25,1.72-7.72,3.11-15.57,4.16-23.53-6.11,3.3-13.11,5.18-20.54,5.18ZM716.66,523.27c3.12,5.98,4.88,12.76,4.88,19.97,0,23.92-19.38,43.32-43.3,43.32s-43.32-19.39-43.32-43.32c0-7.54,1.93-14.63,5.31-20.8,3.8-6.92,9.43-12.69,16.24-16.65,6.39-3.71,13.82-5.85,21.76-5.85,7.42,0,14.41,1.87,20.52,5.16,7.64,4.12,13.9,10.47,17.91,18.18ZM640.37,447.65c4.07,6.59,6.41,14.36,6.41,22.68,0,7.55-1.93,14.64-5.32,20.83-3.8,6.93-9.43,12.69-16.24,16.65-6.39,3.71-13.81,5.84-21.74,5.84-23.92,0-43.32-19.39-43.32-43.32s19.39-43.3,43.32-43.3c8.47,0,16.38,2.43,23.05,6.64,5.62,3.53,10.36,8.32,13.84,13.98ZM715.7,418.07c-3.79,6.54-9.24,11.99-15.78,15.78-6.37,3.7-13.77,5.81-21.68,5.81-8.47,0-16.38-2.43-23.05-6.63-5.62-3.55-10.37-8.35-13.86-14.02-4.06-6.59-6.4-14.36-6.4-22.67,0-23.91,19.39-43.3,43.32-43.3s43.3,19.39,43.3,43.3c0,7.91-2.12,15.33-5.84,21.72ZM228.54,509.48v-79.34h63.14v-63.13h79.34v63.13h63.14v79.34h-63.14v63.14h-79.34v-63.14h-63.14Z"/>
<path class="cls-2" d="M792.62,421c-3.84-22.93-10.36-45.29-19.48-66.87-10.39-24.58-23.86-47.43-40.22-68.28-5.53-7.07-11.41-13.89-17.6-20.48-2.18-2.32-4.39-4.61-6.66-6.87-27.62-27.62-59.79-49.31-95.62-64.46-37.11-15.69-76.51-23.66-117.12-23.66s-80,7.96-117.11,23.66c-35.83,15.16-68.01,36.84-95.63,64.46-2.27,2.27-4.48,4.56-6.66,6.87-6.2,6.59-12.07,13.41-17.6,20.48-16.35,20.85-29.81,43.7-40.21,68.28-15.69,37.11-23.66,76.51-23.66,117.11s7.96,80.02,23.66,117.12c10.33,24.42,23.69,47.14,39.91,67.88,5.52,7.07,11.35,13.89,17.52,20.48,2.3,2.46,4.65,4.88,7.03,7.26,27.62,27.62,59.8,49.32,95.63,64.48,37.11,15.69,76.51,23.64,117.11,23.64s80.02-7.95,117.12-23.64c35.83-15.16,68-36.85,95.62-64.48,2.38-2.38,4.72-4.8,7.03-7.26,6.17-6.59,12.01-13.41,17.52-20.48,16.22-20.74,29.59-43.46,39.92-67.88,9.41-22.25,16.04-45.31,19.83-68.98,2.55-15.81,3.81-31.89,3.81-48.14s-1.38-33.75-4.16-50.24ZM772.76,508.46c-1.05,7.96-2.44,15.81-4.16,23.53-10.41,46.96-32.65,89.47-63.43,124.25-6.35,7.17-13.04,14-20.08,20.48-49.76,45.84-116.2,73.82-189.18,73.82s-139.42-27.98-189.16-73.82c-7.04-6.48-13.75-13.31-20.08-20.48-31.22-35.28-53.66-78.52-63.87-126.29-4.04-18.93-6.18-38.57-6.18-58.72,0-21.16,2.36-41.77,6.82-61.58,10.52-46.81,32.81-89.15,63.57-123.81,6.37-7.17,13.09-14,20.16-20.48,49.7-45.61,115.98-73.44,188.75-73.44s139.05,27.83,188.77,73.44c7.05,6.48,13.79,13.31,20.16,20.48,30.53,34.38,52.7,76.34,63.32,122.72,1.78,7.72,3.23,15.55,4.34,23.5,13.7,7.27,23.02,21.67,23.02,38.26s-9.2,30.81-22.76,38.13Z"/>
</g>
<g>
<path class="cls-1" d="M809.16,285.85H190.85c-20.77,0-37.62,16.85-37.62,37.62v295.15c0,20.77,16.85,37.62,37.62,37.62h618.31c20.78,0,37.62-16.85,37.62-37.62v-295.15c0-20.77-16.85-37.62-37.62-37.62ZM772.76,508.46c-6.11,3.3-13.11,5.18-20.54,5.18s-14.41-1.87-20.52-5.16c-7.64-4.12-13.91-10.47-17.93-18.19-3.11-5.98-4.86-12.76-4.86-19.97,0-7.91,2.12-15.32,5.81-21.7,3.8-6.54,9.25-11.99,15.8-15.78,6.39-3.7,13.8-5.82,21.71-5.82,7.33,0,14.25,1.82,20.29,5.04,13.7,7.27,23.02,21.67,23.02,38.26s-9.2,30.81-22.76,38.13ZM603.48,513.65c-23.92,0-43.32-19.39-43.32-43.32s19.39-43.3,43.32-43.3c8.47,0,16.38,2.43,23.05,6.64,5.62,3.53,10.36,8.32,13.84,13.98,4.07,6.59,6.41,14.36,6.41,22.68,0,7.55-1.93,14.64-5.32,20.83-3.8,6.93-9.43,12.69-16.24,16.65-6.39,3.71-13.81,5.84-21.74,5.84ZM721.54,396.35c0,7.91-2.12,15.33-5.84,21.72-3.79,6.54-9.24,11.99-15.78,15.78-6.37,3.7-13.77,5.81-21.68,5.81-8.47,0-16.38-2.43-23.05-6.63-5.62-3.55-10.37-8.35-13.86-14.02-4.06-6.59-6.4-14.36-6.4-22.67,0-23.91,19.39-43.3,43.32-43.3s43.3,19.39,43.3,43.3ZM634.92,543.24c0-7.54,1.93-14.63,5.31-20.8,3.8-6.92,9.43-12.69,16.24-16.65,6.39-3.71,13.82-5.85,21.76-5.85,7.42,0,14.41,1.87,20.52,5.16,7.64,4.12,13.9,10.47,17.91,18.18,3.12,5.98,4.88,12.76,4.88,19.97,0,23.92-19.38,43.32-43.3,43.32s-43.32-19.39-43.32-43.32ZM434.17,509.48h-63.14v63.14h-79.34v-63.14h-63.14v-79.34h63.14v-63.13h79.34v63.13h63.14v79.34Z"/>
<path class="cls-2" d="M809.16,265.37H190.85c-32.04,0-58.1,26.06-58.1,58.1v295.15c0,32.04,26.06,58.1,58.1,58.1h618.31c32.04,0,58.1-26.06,58.1-58.1v-295.15c0-32.04-26.06-58.1-58.1-58.1ZM846.78,618.62c0,20.77-16.85,37.62-37.62,37.62H190.85c-20.77,0-37.62-16.85-37.62-37.62v-295.15c0-20.77,16.85-37.62,37.62-37.62h618.31c20.78,0,37.62,16.85,37.62,37.62v295.15Z"/>
</g>
<path class="cls-2" d="M391.51,409.66v-63.13h-120.3v63.13h-63.14v120.3h63.14v63.14h120.3v-63.14h63.14v-120.3h-63.14ZM434.17,509.48h-63.14v63.14h-79.34v-63.14h-63.14v-79.34h63.14v-63.13h79.34v63.13h63.14v79.34Z"/>
<path class="cls-2" d="M792.62,421c-7.05-5.77-15.36-10.09-24.45-12.43-5.09-1.32-10.45-2.02-15.95-2.02-3.81,0-7.55.33-11.19.99.65-3.64.99-7.37.99-11.19,0-35.18-28.61-63.78-63.78-63.78s-63.8,28.61-63.8,63.78c0,3.87.35,7.65,1.01,11.33-3.88-.74-7.87-1.13-11.97-1.13-35.18,0-63.8,28.61-63.8,63.78s28.62,63.8,63.8,63.8c4.02,0,7.96-.37,11.78-1.09-.54,3.33-.82,6.73-.82,10.2,0,35.18,28.62,63.8,63.8,63.8s63.78-28.62,63.78-63.8c0-3.43-.27-6.8-.81-10.07,3.57.64,7.26.96,11.01.96,5.66,0,11.15-.74,16.38-2.14,9.08-2.41,17.34-6.77,24.36-12.61,14.07-11.71,23.04-29.35,23.04-49.05s-9.11-37.62-23.39-49.33ZM678.23,353.04c23.92,0,43.3,19.39,43.3,43.3,0,7.91-2.12,15.33-5.84,21.72-3.79,6.54-9.24,11.99-15.78,15.78-6.37,3.7-13.77,5.81-21.68,5.81-8.47,0-16.38-2.43-23.05-6.63-5.62-3.55-10.37-8.35-13.86-14.02-4.06-6.59-6.4-14.36-6.4-22.67,0-23.91,19.39-43.3,43.32-43.3ZM625.21,507.81c-6.39,3.71-13.81,5.84-21.74,5.84-23.92,0-43.32-19.39-43.32-43.32s19.39-43.3,43.32-43.3c8.47,0,16.38,2.43,23.05,6.64,5.62,3.53,10.36,8.32,13.84,13.98,4.07,6.59,6.41,14.36,6.41,22.68,0,7.55-1.93,14.64-5.32,20.83-3.8,6.93-9.43,12.69-16.24,16.65ZM678.23,586.56c-23.92,0-43.32-19.39-43.32-43.32,0-7.54,1.93-14.63,5.31-20.8,3.8-6.92,9.43-12.69,16.24-16.65,6.39-3.71,13.82-5.85,21.76-5.85,7.42,0,14.41,1.87,20.52,5.16,7.64,4.12,13.9,10.47,17.91,18.18,3.12,5.98,4.88,12.76,4.88,19.97,0,23.92-19.38,43.32-43.3,43.32ZM772.76,508.46c-6.11,3.3-13.11,5.18-20.54,5.18s-14.41-1.87-20.52-5.16c-7.64-4.12-13.91-10.47-17.93-18.19-3.11-5.98-4.86-12.76-4.86-19.97,0-7.91,2.12-15.32,5.81-21.7,3.8-6.54,9.25-11.99,15.8-15.78,6.39-3.7,13.8-5.82,21.71-5.82,7.33,0,14.25,1.82,20.29,5.04,13.7,7.27,23.02,21.67,23.02,38.26s-9.2,30.81-22.76,38.13Z"/>
</g>
<g>
<polygon points="946.58 812.72 946.58 824.18 958.38 824.18 958.38 835.98 934.77 835.98 934.77 824.53 900.4 824.53 900.4 847.44 946.58 847.44 946.58 858.9 958.38 858.9 958.38 882.51 946.58 882.51 946.58 893.96 888.6 893.96 888.6 882.51 877.14 882.51 877.14 870.7 900.4 870.7 900.4 882.16 934.77 882.16 934.77 859.24 888.6 859.24 888.6 847.79 877.14 847.79 877.14 824.18 888.6 824.18 888.6 812.72 946.58 812.72"/>
<g>
<path d="M666.56,812.72v11.46h11.8v58.33h-11.8v11.46h-57.98v-11.46h-11.46v-58.33h11.46v-11.46h57.98ZM654.75,824.53h-34.37v57.63h34.37v-57.63Z"/>
<path d="M481.5,835.98v-11.8h-11.45v-11.46h-35.07v11.46h-11.46v11.8h-11.8v57.98h23.61v-23.26h34.37v23.26h23.26v-57.98h-11.46ZM469.7,858.89h-34.37v-22.91h11.45v-11.46h11.46v11.46h11.46v22.91Z"/>
<g>
<polygon points="249.93 812.72 249.93 882.16 284.65 882.16 284.65 812.72 307.91 812.72 307.91 882.51 296.46 882.51 296.46 893.96 238.13 893.96 238.13 882.51 226.67 882.51 226.67 812.72 249.93 812.72"/>
<g>
<polygon points="157.58 812.72 157.58 824.18 169.04 824.18 169.04 835.98 180.49 835.98 180.49 824.18 191.95 824.18 191.95 812.72 215.21 812.72 215.21 893.96 191.95 893.96 191.95 847.79 180.49 847.79 180.49 870.7 168.69 870.7 168.69 847.79 157.58 847.79 157.58 893.96 133.97 893.96 133.97 812.72 157.58 812.72"/>
<polygon points="122.86 812.72 122.86 824.53 64.88 824.53 64.88 847.44 111.06 847.44 111.06 859.24 64.88 859.24 64.88 882.16 122.86 882.16 122.86 893.96 41.62 893.96 41.62 812.72 122.86 812.72"/>
</g>
</g>
<polygon points="863.41 812.72 863.41 882.51 851.95 882.51 851.95 893.96 793.63 893.96 793.63 882.51 782.17 882.51 782.17 870.7 805.43 870.7 805.43 882.16 840.15 882.16 840.15 812.72 863.41 812.72"/>
<polygon points="354.09 812.72 354.09 882.16 400.61 882.16 400.61 893.96 330.83 893.96 330.83 812.72 354.09 812.72"/>
<polygon points="585.66 812.72 585.66 824.53 562.4 824.53 562.4 893.96 539.14 893.96 539.14 824.53 515.88 824.53 515.88 812.72 585.66 812.72"/>
<path d="M770.71,859.24v-35.06h-11.46v-11.46h-69.78v81.24h23.61v-23.26h11.11v11.8h11.8v11.46h34.72v-11.8h-11.46v-11.46h-11.45v-11.46h22.91ZM747.45,847.44h-11.46v11.45h-22.91v-34.37h34.37v22.92Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

26
docs/emulatorjs-type.svg Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
<defs>
<style>
.cls-1 {
fill: #fff;
}
</style>
</defs>
<polygon class="cls-1" points="966 457.61 966 469.57 978.31 469.57 978.31 481.89 953.68 481.89 953.68 469.93 917.81 469.93 917.81 493.84 966 493.84 966 505.8 978.31 505.8 978.31 530.43 966 530.43 966 542.39 905.49 542.39 905.49 530.43 893.54 530.43 893.54 518.11 917.81 518.11 917.81 530.07 953.68 530.07 953.68 506.16 905.49 506.16 905.49 494.2 893.54 494.2 893.54 469.57 905.49 469.57 905.49 457.61 966 457.61"/>
<g>
<path class="cls-1" d="M673.8,457.61v11.96h12.32v60.86h-12.32v11.96h-60.5v-11.96h-11.96v-60.86h11.96v-11.96h60.5ZM661.48,469.93h-35.87v60.14h35.87v-60.14Z"/>
<path class="cls-1" d="M480.7,481.89v-12.31h-11.95v-11.96h-36.59v11.96h-11.96v12.31h-12.31v60.5h24.64v-24.27h35.86v24.27h24.27v-60.5h-11.96ZM468.38,505.79h-35.86v-23.91h11.95v-11.96h11.96v11.96h11.96v23.91Z"/>
<g>
<polygon class="cls-1" points="239.06 457.61 239.06 530.07 275.29 530.07 275.29 457.61 299.56 457.61 299.56 530.43 287.6 530.43 287.6 542.39 226.74 542.39 226.74 530.43 214.78 530.43 214.78 457.61 239.06 457.61"/>
<g>
<polygon class="cls-1" points="142.69 457.61 142.69 469.57 154.64 469.57 154.64 481.89 166.6 481.89 166.6 469.57 178.56 469.57 178.56 457.61 202.83 457.61 202.83 542.39 178.56 542.39 178.56 494.2 166.6 494.2 166.6 518.11 154.28 518.11 154.28 494.2 142.69 494.2 142.69 542.39 118.05 542.39 118.05 457.61 142.69 457.61"/>
<polygon class="cls-1" points="106.46 457.61 106.46 469.93 45.96 469.93 45.96 493.84 94.14 493.84 94.14 506.16 45.96 506.16 45.96 530.07 106.46 530.07 106.46 542.39 21.69 542.39 21.69 457.61 106.46 457.61"/>
</g>
</g>
<polygon class="cls-1" points="879.21 457.61 879.21 530.43 867.26 530.43 867.26 542.39 806.39 542.39 806.39 530.43 794.44 530.43 794.44 518.11 818.71 518.11 818.71 530.07 854.94 530.07 854.94 457.61 879.21 457.61"/>
<polygon class="cls-1" points="347.74 457.61 347.74 530.07 396.29 530.07 396.29 542.39 323.47 542.39 323.47 457.61 347.74 457.61"/>
<polygon class="cls-1" points="589.39 457.61 589.39 469.93 565.11 469.93 565.11 542.39 540.84 542.39 540.84 469.93 516.57 469.93 516.57 457.61 589.39 457.61"/>
<path class="cls-1" d="M782.48,506.16v-36.58h-11.96v-11.96h-72.81v84.77h24.64v-24.27h11.59v12.31h12.31v11.96h36.23v-12.31h-11.96v-11.96h-11.95v-11.96h23.91ZM758.21,493.84h-11.96v11.95h-23.91v-35.86h35.86v23.92Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

4487
docs/old-Logo.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 170 KiB

View File

@ -45,7 +45,7 @@
}
#box:hover, #box[drag] {
border-color: #38f;
border-color: #1AAFFF;
color: #ddd
}
@ -88,7 +88,7 @@
.logo {
width: 130px;
height: 130px;
filter: drop-shadow(0 0 10px white);
filter: drop-shadow(0 0 8px white);
}
#top {
@ -104,23 +104,24 @@
<br>
</div>
<div id="box">
<input type = file id = input>
<input type="file" id ="input" title="Upload" />
Drag ROM file or click here
</div>
<script>
let enableDebug = false;
let enableThreads = false;
let browserMode;
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
if (parseInt(urlParams.get('debug')) === 1 || urlParams.get('debug') === "true") {
if (parseInt(urlParams.get("debug")) === 1 || urlParams.get("debug") === "true") {
enableDebug = true;
console.log("Debug is enabled");
} else {
console.log("Debug is disabled");
}
if (parseInt(urlParams.get('threads')) === 1 || urlParams.get('threads') === "true") {
if (parseInt(urlParams.get("threads")) === 1 || urlParams.get("threads") === "true") {
if (window.SharedArrayBuffer) {
enableThreads = true;
console.log("Threads are enabled");
@ -132,9 +133,13 @@
console.log("Threads are disabled");
}
if (urlParams.get('rom')) {
console.log(`Loading ROM from URL: roms/${urlParams.get('rom')}`);
run(false, urlParams.get('rom'));
if (urlParams.get("browserMode")) {
browserMode = urlParams.get("browserMode");
}
if (urlParams.get("rom")) {
console.log(`Loading ROM from URL: roms/${urlParams.get("rom")}`);
run(false, urlParams.get("rom"));
}
async function run(upload, file) {
@ -165,6 +170,9 @@
if (["d64"].includes(ext))
return "vice_x64sc"
if (["md", "sg", "smd", "gen"].includes(ext))
return "segaMD"
if (["nds", "gba", "gb", "z64", "n64"].includes(ext))
return ext
@ -199,9 +207,20 @@
"Commodore 128": "vice_x128",
"Commodore VIC20": "vice_xvic",
"Commodore Plus/4": "vice_xplus4",
"Commodore PET": "vice_xpet"
"Commodore PET": "vice_xpet",
}
if (enableThreads) {
coreValues["DOSBOX-PURE"] = "dosbox_pure";
coreValues["PlayStation Portable"] = "ppsspp";
}
for (let core in coreValues) {
if (core.toLowerCase() === ext) {
resolve(core)
}
}
const cores = Object.keys(coreValues).sort().reduce(
(obj, key) => {
obj[key] = coreValues[key];
@ -253,6 +272,9 @@
window.EJS_DEBUG_XX = enableDebug;
window.EJS_disableDatabases = true;
window.EJS_threads = enableThreads;
if (browserMode) {
window.EJS_browserMode = browserMode;
}
script.src = "data/loader.js";
document.body.appendChild(script);

View File

@ -1,8 +1,8 @@
import path from "path";
import { fileURLToPath } from "url";
import minify from "@node-minify/core";
import terser from "@node-minify/terser";
import cleanCSS from "@node-minify/clean-css";
import { minify } from "@node-minify/core";
import { terser } from "@node-minify/terser";
import { cleanCss } from '@node-minify/clean-css';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@ -21,7 +21,7 @@ async function doMinify() {
console.log("Minified JS");
});
await minify({
compressor: cleanCSS,
compressor: cleanCss,
input: path.join(rootPath, "data/emulator.css"),
output: path.join(rootPath, "data/emulator.min.css"),
})

View File

@ -1,6 +1,6 @@
{
"name": "@emulatorjs/emulatorjs",
"version": "4.2.3",
"version": "4.2.4",
"type": "module",
"description": "EmulatorJS is a frontend for RetroArch in the web browser.",
"homepage": "https://emulatorjs.org",
@ -17,19 +17,23 @@
"start": "http-server",
"minify": "node minify/minify.js",
"build": "node build.js",
"update": "node update.js"
"update": "node update.js",
"docs": "jsdoc data/src/*.js -d jsdoc"
},
"dependencies": {
"@node-minify/clean-css": "^9.0.1",
"@node-minify/core": "^9.0.2",
"@node-minify/terser": "^9.0.1",
"@node-minify/clean-css": "^10.2.0",
"@node-minify/core": "^10.2.0",
"@node-minify/terser": "^10.2.0",
"http-server": "^14.1.1",
"node-7z": "^3.0.0",
"node-fetch": "^3.3.2",
"nipplejs": "^0.10.2",
"socket.io": "^4.8.1"
"node-7z": "^3.0.0"
},
"optionalDependencies": {
"@emulatorjs/cores": "latest"
},
"devDependencies": {
"jsdoc": "^4.0.4",
"nipplejs": "^0.10.2",
"node-fetch": "^3.3.2",
"socket.io": "^4.8.1"
}
}

View File

@ -5,6 +5,7 @@ import fetch from 'node-fetch';
const args = process.argv.slice(2);
const versionArg = args.find(arg => arg.startsWith('--ejs_v='));
const devArg = args.find(arg => arg.startsWith('--dev='));
const depsArg = args.find(arg => arg.startsWith('--deps='));
const update_version = versionArg ? versionArg.split('=')[1] : process.env.ejs_v;
const dev = devArg ? devArg.split('=')[1] : null;
let version;
@ -26,12 +27,18 @@ const updateDependencies = async () => {
try {
fs.copyFileSync(socket_io, ejs_socket_io);
if (!fs.readFileSync(ejs_socket_io, 'utf8').endsWith('\n')) {
fs.appendFileSync(ejs_socket_io, '\n');
}
} catch(error) {
console.error("Error updating socket.io:", error.message);
}
try {
fs.copyFileSync(nipplejs, ejs_nipplejs);
if (!fs.readFileSync(ejs_nipplejs, 'utf8').endsWith('\n')) {
fs.appendFileSync(ejs_nipplejs, '\n');
}
} catch(error) {
console.error("Error updating nipplejs:", error.message);
}
@ -117,7 +124,9 @@ if (!update_version) {
}
console.log("Updating EmulatorJS dependencies...");
await updateDependencies();
if (depsArg) {
await updateDependencies();
}
if (update_version || dev === "false" || dev === "true") {
console.log("Updating EmulatorJS version...");
await updateVersion(update_version || version);