Skip to content

Commit

Permalink
chore: update demo
Browse files Browse the repository at this point in the history
  • Loading branch information
arianrhodsandlot committed Feb 25, 2024
1 parent 530aa27 commit 6f5cd04
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 181 deletions.
158 changes: 15 additions & 143 deletions demo/demo.js
Original file line number Diff line number Diff line change
@@ -1,164 +1,26 @@
const core = new URLSearchParams(location.search).get('core')
const raUserdataDir = '/home/web_user/retroarch/userdata/'
const raConfigPath = `${raUserdataDir}retroarch.cfg`
const canvas = document.querySelector('#canvas')

function delay(time = 1) {
return new Promise((resolve) => setTimeout(resolve, time))
}

function loadScript(src) {
const script = document.createElement('script')
script.setAttribute('src', src)
return new Promise((resolve, reject) => {
function onScriptLoaded() {
script.remove()
resolve()
}
function onScriptError(event) {
reject(event)
}
script.addEventListener('load', onScriptLoaded)
script.addEventListener('error', onScriptError)
document.body.append(script)
})
}

const messageQueue = []
function getDefaultModule() {
return {
noInitialRun: true,
canvas,

preRun: [
() => {
const { FS } = window
FS.init(() => {
// Return ASCII code of character, or null if no input
while (messageQueue.length > 0) {
const msg = messageQueue[0][0]
const index = messageQueue[0][1]
if (index >= msg.length) {
messageQueue.shift()
} else {
messageQueue[0][1] = index + 1
// assumption: msg is a uint8array
return msg[index]
}
}
return null
})
},
],
}
}

async function loadEmscripten(core) {
const coreFileNames = [`${core}_libretro.js`, `${core}_libretro_emscripten.bc_libretro.js`]
const sources = coreFileNames.map((n) => `../dist/cores/${n}`)
const defaultModule = getDefaultModule()
Object.assign(window, { Module: defaultModule })
let loaded = false
for (const source of sources) {
if (!loaded) {
try {
await loadScript(source)
loaded = true
} catch {}
}
}
const { Module } = window
while (!Module.asm) {
await delay(10)
}
}

async function createEmscriptenFS() {
const { FS, PATH, ERRNO_CODES } = window

const {
default: { EmscriptenFS, FileSystem, initialize },
} = await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm')
const inMemoryFS = new FileSystem.InMemory()
const mountableFS = new FileSystem.MountableFileSystem()
inMemoryFS.empty()
try {
mountableFS.umount(raUserdataDir)
} catch {}
mountableFS.mount(raUserdataDir, inMemoryFS)

initialize(mountableFS)

return new EmscriptenFS(FS, PATH, ERRNO_CODES)
}

async function writeConfigFile({ path, content }) {
const { FS } = window
const dir = path.slice(0, path.lastIndexOf('/'))
FS.mkdirTree(dir)
FS.writeFile(path, content)
await delay(100)
}

async function writeFile(file, dir) {
const { FS } = window
const { name } = file
const buffer = await file.arrayBuffer()
const dataView = new Uint8Array(buffer)
FS.createDataFile('/', name, dataView, true, false)
const data = FS.readFile(name, { encoding: 'binary' })
FS.mkdirTree(`${raUserdataDir}${dir}/`)
FS.writeFile(`${raUserdataDir}${dir}/${name}`, data, { encoding: 'binary' })
FS.unlink(name)
await delay(100)
}

async function prepare(file) {
if (!('FS' in window)) {
await loadEmscripten(core)

const { FS } = window

const emscriptenFS = await createEmscriptenFS()
FS.mount(emscriptenFS, { root: '/home' }, '/home')
const raConfig = 'menu_driver = rgui'
await writeConfigFile({ path: raConfigPath, content: raConfig })
}
}

const addRomButton = document.querySelector('#add-rom')
const addBiosButton = document.querySelector('#add-bios')
const runButton = document.querySelector('#run')
const select = document.querySelector('#core')

const roms = []
const rom = []
async function addRom() {
await prepare()
const [fileHandle] = await showOpenFilePicker()
const file = await fileHandle.getFile()
await writeFile(file, 'content')
roms.push(file)
rom.push(file)
}

const bios = []
async function addBios() {
await prepare()
const [fileHandle] = await showOpenFilePicker()
const file = await fileHandle.getFile()
await writeFile(file, 'system')
bios.push(file)
}

async function run() {
const { Module } = window
const [rom] = roms
const raArgs = [`/home/web_user/retroarch/userdata/content/${rom.name}`]
Module.callMain(raArgs)
if (canvas) {
canvas.style.setProperty('display', 'block')
Module.setCanvasSize(innerWidth, innerHeight)
document.addEventListener('resize', () => {
Module.setCanvasSize(innerWidth, innerHeight)
})
}
await Nostalgist.launch({ core, rom, bios })
}

function onSelectCore() {
Expand All @@ -176,3 +38,13 @@ if (core) {
addBiosButton.hidden = false
runButton.hidden = false
}

Nostalgist.configure({
resolveCoreJs(core) {
return '/dist/cores/' + core + '_libretro.js'
},

resolveCoreWasm(core) {
return '/dist/cores/' + core + '_libretro.wasm'
},
})
29 changes: 1 addition & 28 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@
left: 20px;
z-index: 11;
}
#canvas {
background-color: black;
background-image: repeating-linear-gradient(45deg, #000 25%, transparent 25%, transparent 75%, #000 75%, #000),
repeating-linear-gradient(45deg, #000 25%, #222 25%, #222 75%, #000 75%, #000);
background-position: 0 0, 15px 15px;
background-size: 30px 30px;
cursor: default;
display: block;
image-rendering: pixelated;
inset: 0;
max-height: 100%;
max-width: 100%;
position: fixed;
display: none;
z-index: 10;
}
</style>
</head>
<body>
Expand All @@ -49,25 +33,14 @@
<option value="">Select a core</option>
<option value="a5200">a5200</option>
<option value="fbneo">fbneo</option>
<option value="fceumm">fceumm</option>
<option value="gearboy">gearboy</option>
<option value="genesis_plus_gx">genesis_plus_gx</option>
<option value="mednafen_lynx">mednafen_lynx</option>
<option value="mednafen_ngp">mednafen_ngp</option>
<option value="mednafen_vb">mednafen_vb</option>
<option value="mednafen_wswan">mednafen_wswan</option>
<option value="mgba">mgba</option>
<option value="nestopia">nestopia</option>
<option value="picodrive">picodrive</option>
<option value="prosystem">prosystem</option>
<option value="snes9x">snes9x</option>
<option value="stella2014">stella2014</option>
</select>
<button type="button" id="add-rom" hidden>Add a ROM file</button>
<button type="button" id="add-bios" hidden>Add a BIOS file</button>
<button type="button" id="run" hidden>Run</button>
</div>
<canvas id="canvas"></canvas>
<script src="https://cdn.jsdelivr.net/npm/nostalgist"></script>
<script type="module" src="./demo.js"></script>
</body>
</html>
12 changes: 2 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,10 @@ In addition, RetroArch cores will be uploaded to [NPM](https://www.npmjs.com/pac

## Credits
+ Upstream Emulators:
+ [beetle-lynx-libretro](https://github.com/libretro/beetle-lynx-libretro) Emulator for Atari Lynx.
+ [a5200](https://github.com/libretro/a5200) Emulator for Atari 5200.
+ [FBNeo](https://github.com/libretro/FBNeo) Emulator for arcades.
+ [prosystem-libretro](https://github.com/libretro/prosystem-libretro) Emulator for Atari 7800.
+ [Genesis-Plus-GX](https://github.com/libretro/Genesis-Plus-GX) Emulator for Sega Genesis and some other consoles.
+ [stella2014-libretro](https://github.com/libretro/stella2014-libretro) Emulator for Atari 2600.
+ [snes9x](https://github.com/libretro/snes9x) Emulator for SNES.
+ [mgba](https://github.com/libretro/mgba) Emulator for GBA/Game Boy/Game Boy Color.
+ [nestopia](https://github.com/libretro/nestopia) Emulator for NES.
+ [beetle-vb-libretro](https://github.com/libretro/beetle-vb-libretro) Emulator for Virtual Boy.
+ [libretro-fceumm](https://github.com/libretro/libretro-fceumm) Emulator for NES.
+ [a5200](https://github.com/libretro/a5200) Emulator for Atari 5200.
+ [beetle-wswan-libretro](https://github.com/libretro/beetle-wswan-libretro) Emulator for WonderSwan.
+ [beetle-ngp-libretro](https://github.com/libretro/beetle-ngp-libretro) Emulator for Neo Geo Pocket.
+ [RetroArch](https://github.com/libretro/retroarch) We mainly rely on the fantastic work done by them.
+ [Emscripten](https://github.com/emscripten-core/emscripten) Without which we could not run native codes inside browsers.
+ [webretro](https://github.com/BinBashBanana/webretro) Parts of our patches made on RetroArch is adapted from here.
Expand Down

0 comments on commit 6f5cd04

Please sign in to comment.