nes.js 2.06 KiB
import jsnes from "jsnes";
var SCREEN_WIDTH = 256;
var SCREEN_HEIGHT = 240;
var FRAMEBUFFER_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
var framebuffer_u8, framebuffer_u32;
var nes = new jsnes.NES({
onFrame: function (framebuffer_24) {
for (var i = 0; i < FRAMEBUFFER_SIZE; i++)
framebuffer_u32[i] = 0xff000000 | framebuffer_24[i];
postMessage(framebuffer_u8);
},
});
var pressedKeys = {};
onmessage = (msg) => {
const keys = {
up: jsnes.Controller.BUTTON_UP,
down: jsnes.Controller.BUTTON_DOWN,
left: jsnes.Controller.BUTTON_LEFT,
right: jsnes.Controller.BUTTON_RIGHT,
a: jsnes.Controller.BUTTON_A,
b: jsnes.Controller.BUTTON_B,
start: jsnes.Controller.BUTTON_START,
select: jsnes.Controller.BUTTON_SELECT,
};
for (let i = 0; i < Object.keys(keys).length; i++) {
const key = Object.keys(keys)[i];
const val = keys[key];
if (pressedKeys[key] && !msg.data.keys[key]) {
// key was pressed and no longer is pressed
nes.buttonUp(1, val);
} else if (!pressedKeys[key] && msg.data.keys[key]) {
// key was not pressed but now it is
nes.buttonDown(1, val);
}
}
pressedKeys = msg.data.keys;
};
function nes_init() {
// Allocate framebuffer array.
var buffer = new ArrayBuffer(SCREEN_WIDTH * SCREEN_HEIGHT * 4);
framebuffer_u8 = new Uint8ClampedArray(buffer);
framebuffer_u32 = new Uint32Array(buffer);
}
function nes_boot(rom_data) {
nes.loadROM(rom_data);
}
function nes_load_url(path) {
nes_init();
var req = new XMLHttpRequest();
req.open("GET", path);
req.overrideMimeType("text/plain; charset=x-user-defined");
req.onerror = () => console.log(`Error loading ${path}: ${req.statusText}`);
req.onload = function () {
if (this.status === 200) {
nes_boot(this.responseText);
function doit() {
setTimeout(() => {
doit();
nes.frame();
}, 1000.0 / 60);
}
doit();
} else if (this.status === 0) {
// Aborted, so ignore error
} else {
req.onerror();
}
};
req.send();
}
nes_load_url("main.rom");