Skip to content

Instantly share code, notes, and snippets.

@ybootin
Last active September 13, 2016 11:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ybootin/557c2f7f4548107bfe24af6d89fe91d5 to your computer and use it in GitHub Desktop.
Save ybootin/557c2f7f4548107bfe24af6d89fe91d5 to your computer and use it in GitHub Desktop.

#MAME js loader Proof Of Concept

A no dependency simple proof of concept to run MAME in a browser

Test outrun rom here : https://rawgit.com/ybootin/557c2f7f4548107bfe24af6d89fe91d5/raw/af839a36054a5abf51929300cd1d92f2e4279a7e/mame.html

Advanced Usage

You can compile your own emulator here : https://github.com/mamejs/mamejs-compiler

Clone this gist, create a roms folder, and put your roms inside (cps1,cps2, system16a & b, outrun, twincobra, snowbros are only working) Update the var game object to match the good path, and use the good driver.

Should work !

<!doctype html>
<html>
<head></head>
<body>
<h1>Proof Of Concept : a simple MAME loader</h1>
<div id="loading">Loading game, please wait !</div>
<div class="container">
<canvas id="display" style="width:320px;height:224px" width="320" height="224"></canvas>
</div>
<script>
// legacy, must be define
var JSMESS = JSMESS || {};
JSMESS.ready = function (f) { f(); };
var game = {
files : {
//'snowbros.zip': '../emulators/roms/snowbros.zip',
//'twincobr.zip': '../emulators/roms/twincobr.zip',
//'bublbobl.zip': '../emulators/bublbobl.zip',
//'shinobi.zip': '../emulators/roms/shinobi.zip',
//'sf2.zip' : '../emulators/roms/sf2.zip',
//'ghouls.zip' : '../emulators/cps1/ghouls.zip',
//'outrun.zip' : '../emulators/outrun/outrun.zip',
//'outrun.cfg' : '../emulators/outrun/outrun.cfg',
'outrun.zip': 'https://cors.archive.org/cors/arcade_outrun/outrun.zip',
},
driver: 'outrun',
emulator: 'https://rawgit.com/mamejs/mamejs-emulators/master/mamejs-serie1.js',
resolution: {
width: 320,
height: 224
}
}
var canvas = document.getElementById('display')
function fetchFile(url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
let errorMsg = 'error loading ' + url
xhr.onload = function (e) {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(errorMsg + ' : status code ' + xhr.status);
}
}
xhr.onerror = function (e) {
reject(errorMsg + ' : ' + e.toString());
};
xhr.send();
});
}
// Fetch all game files
Promise.all(Object.keys(game.files).map(function(romName) {
return fetchFile(game.files[romName]).then(function(arrayBuffer) {
return {
rom: romName,
data: arrayBuffer
}
})
})).then(function(data) { // Promise.all will return an array of {rom: string, data: ArrayBuffer}
// MAME Module for emscripten
window.Module = {
arguments: [
game.driver,
'-verbose',
'-rompath',
'/roms',
'-resolution',
game.resolution.width + 'x' + game.resolution.height,
'-samplerate',
'48000',
// '-sound',
// 'none',
],
screenIsReadOnly: true,
print: function (text) {
console.log('MAME - ' + text);
},
canvas: display,
noInitialRun: false,
preInit: function () {
// create and mount FS into /roms folder
FS.mkdir('/roms');
FS.mount(MEMFS, {root: '/'}, '/roms');
// write all game files into the /roms folder
data.forEach(function(file) {
FS.writeFile('/roms/' + file.rom, new Uint8Array(file.data), {
encoding: 'binary'
})
})
}
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.onload = Promise.resolve
script.onerror = Promise.reject
script.src = game.emulator;
document.getElementsByTagName('head')[0].appendChild(script);
}).then(function() {
document.getElementById('loading').style.display = 'none'
}).catch(function(error) {
document.getElementById('loading').innerHTML = 'error : ' + error
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment