nes-js
Version:
JavaScript NES emulator
357 lines (308 loc) • 11.2 kB
HTML
<html>
<head>
<script type="text/javascript" src="build/nes.js"></script>
<script type="text/javascript">
var __nes;
/**
*
*/
function __dragOverHandler(e) {
e.preventDefault();
}
/**
*
*/
function __dropRomImage(e) {
e.preventDefault();
var file = e.dataTransfer.files[0];
var reader = new FileReader();
reader.onload = function(e) {
__putMessage('Loading done.');
__run(e.target.result);
};
reader.onerror = function(e) {
for(var key in reader.error) {
__putMessage(key + '=' + reader.error[key]);
}
};
reader.readAsArrayBuffer(file);
__putMessage('')
__putMessage('Loading rom image...')
}
/**
*
*/
function __loadRom() {
var url = document.getElementById('romList').selectedOptions[0].value;
var request = new XMLHttpRequest();
request.responseType = 'arraybuffer';
request.onload = function() {
__putMessage('Loading done.');
__run(request.response);
};
request.onerror = function(e) {
__putMessage('failed to load.');
};
request.open('GET', url, true);
request.send(null);
__putMessage('')
__putMessage('Loading rom image...')
__ROMloaded();
}
/**
*
*/
function __init() {
document.getElementById('loadROMButton').disabled = false;
document.getElementById('dumpROMButton').disabled = true;
document.getElementById('dumpRegButton').disabled = true;
document.getElementById('dumpRAMButton').disabled = true;
document.getElementById('dumpVRAMButton').disabled = true;
document.getElementById('dumpSPRRAMButton').disabled = true;
document.getElementById('stopButton').disabled = true;
document.getElementById('stepButton').disabled = true;
document.getElementById('resumeButton').disabled = true;
}
/**
*
*/
function __ROMloaded() {
document.getElementById('loadROMButton').disabled = true;
document.getElementById('dumpROMButton').disabled = true;
document.getElementById('dumpRegButton').disabled = true;
document.getElementById('dumpRAMButton').disabled = true;
document.getElementById('dumpVRAMButton').disabled = true;
document.getElementById('dumpSPRRAMButton').disabled = true;
document.getElementById('stopButton').disabled = true;
document.getElementById('stepButton').disabled = true;
document.getElementById('resumeButton').disabled = true;
}
/**
*
*/
function __NESran() {
document.getElementById('loadROMButton').disabled = true;
document.getElementById('dumpROMButton').disabled = true;
document.getElementById('dumpRegButton').disabled = true;
document.getElementById('dumpRAMButton').disabled = true;
document.getElementById('dumpVRAMButton').disabled = true;
document.getElementById('dumpSPRRAMButton').disabled = true;
document.getElementById('stopButton').disabled = false;
document.getElementById('stepButton').disabled = true;
document.getElementById('resumeButton').disabled = true;
}
/**
*
*/
function __NESstopped() {
document.getElementById('loadROMButton').disabled = true;
document.getElementById('dumpROMButton').disabled = false;
document.getElementById('dumpRegButton').disabled = false;
document.getElementById('dumpRAMButton').disabled = false;
document.getElementById('dumpVRAMButton').disabled = false;
document.getElementById('dumpSPRRAMButton').disabled = false;
document.getElementById('stopButton').disabled = true;
document.getElementById('stepButton').disabled = false;
document.getElementById('resumeButton').disabled = false;
}
/**
*
*/
function __run(arrayBuffer) {
try {
var rom = new NesJs.Rom(arrayBuffer);
} catch(e) {
__putMessage('');
__putMessage(e.toString());
return;
}
__putMessage('');
__putMessage('Rom Header info');
__putMessage(rom.header.dump());
var nes = new NesJs.Nes();
nes.addEventListener('fps', function(fps) {
document.getElementById('fps').innerText = fps.toFixed(2);
});
nes.setRom(rom);
nes.setDisplay(new NesJs.Display(document.getElementById('mainCanvas')));
try {
nes.setAudio(new NesJs.Audio());
} catch(e) {
__putMessage('');
__putMessage('Disables audio because this browser does not seems to support WebAudio.');
}
window.onkeydown = function(e) { nes.handleKeyDown(e) };
window.onkeyup = function(e) { nes.handleKeyUp(e) };
__nes = nes; // for debug on console.
__putMessage('');
__putMessage('bootup.');
nes.bootup();
__putMessage('runs.');
__NESran();
nes.run();
}
/**
*
*/
function __pushDumpROM() {
__putMessage(__nes.dumpRom());
}
/**
*
*/
function __pushDumpReg() {
__putMessage(__nes.dumpCpu());
__putMessage(__nes.dumpPpu());
}
/**
*
*/
function __pushDumpRAM() {
__putMessage(__nes.dumpRam());
}
/**
*
*/
function __pushDumpVRAM() {
__putMessage(__nes.dumpVRam());
}
/**
*
*/
function __pushDumpSPRRAM() {
__putMessage(__nes.dumpSprRam());
}
/**
*
*/
function __pushStopButton() {
__nes.stop();
__putMessage('stopped.');
__NESstopped();
}
/**
*
*/
function __pushStepButton() {
__nes.runStep();
__putMessage(__nes.dumpCpu());
}
/**
*
*/
function __pushResumeButton() {
__nes.resume();
__putMessage('resumed.');
__NESran();
}
/**
*
*/
function __pushPadButton(key) {
if(! __nes)
return;
__nes.pad1.pressButton(parseInt(key.split('_')[1]));
}
/**
*
*/
function __releasePadButton(key) {
if(! __nes)
return;
__nes.pad1.releaseButton(parseInt(key.split('_')[1]));
}
/**
*
*/
function __putMessage(str) {
var area = document.getElementById('dump');
area.firstChild.appendData(str + '\n');
area.scrollTop = area.scrollHeight;
}
window.addEventListener('drop', __dropRomImage, false);
window.addEventListener('dragover', __dragOverHandler, false);
</script>
</head>
<body onload="__init()">
<p>
<select id="romList">
<option value="./roms/nestest.nes">nestest</option>
<option value="./roms/Sgt. Helmet - Training Day (2013)(The Mojon Twins)[!].nes" selected>Sgt. Helmet</option>
<option value="./roms/pong1k.nes">pong1k</option>
<option value="./roms/The Invasion.nes">The Invasion</option>
<option value="./roms/mguard.nes">mguard</option>
</select>
<button id="loadROMButton" onclick="__loadRom()">load rom</button><br />
Select rom from the list or drag and drop your own rom into this window to start.
</p>
<p>
<canvas id="mainCanvas" width="256" height="240"
style="border:1px solid black; width:512px; height:480px;"></canvas>
<span id="fps"></span> fps
</p>
<div>
<table>
<tr>
<td></td>
<td><button id="pad1_4" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">U</button></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><button id="pad1_6" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">L</button></td>
<td></td>
<td><button id="pad1_7" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">R</button></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><button id="pad1_5" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">D</button></td>
<td></td>
<td><button id="pad1_2" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">SELECT</button></td>
<td><button id="pad1_3" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">START</button></td>
<td><button id="pad1_1" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">B</button></td>
<td><button id="pad1_0" onmousedown="__pushPadButton(this.id)"
onclick="__releasePadButton(this.id)">A</button></td>
</tr>
</table>
</div>
<p>
<div>
<button id="dumpROMButton" onclick="__pushDumpROM()">dump ROM</button>
<button id="dumpRegButton" onclick="__pushDumpReg()">dump CPU/PPU reg</button>
<button id="dumpRAMButton" onclick="__pushDumpRAM()">dump CPU RAM</button>
<button id="dumpVRAMButton" onclick="__pushDumpVRAM()">dump PPU VRAM</button>
<button id="dumpSPRRAMButton" onclick="__pushDumpSPRRAM()">dump PPU SPRRAM</button>
<button id="stopButton" onclick="__pushStopButton()">stop</button>
<button id="stepButton" onclick="__pushStepButton()">step</button>
<button id="resumeButton" onclick="__pushResumeButton()">resume</button>
</div>
<textarea id="dump" cols="128" rows="16" readonly="readonly"> </textarea>
</p>
<p>
Thanks for the public domain NES roms.
</p>
<ul>
<li><a href="http://pdroms.de/category/nintendoentertainmentsystem">http://pdroms.de/category/nintendoentertainmentsystem</a></li>
<li><a href="http://slydogstudios.org/index.php/1k-series/">http://slydogstudios.org/index.php/1k-series/</a></li>
<li><a href="http://www.mojontwins.com/juegos_mojonos/sgt-helmet-training-day-nes/">http://www.mojontwins.com/juegos_mojonos/sgt-helmet-training-day-nes/</a></li>
</ul>
<p>
<a href="https://github.com/takahirox/nes-js">Source code at GitHub</a>
</p>
</body>
</html>