j"19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAutMÂ<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Embedding Example</title>
<script type="text/javascript" src="b://aded9f959df1b3648741eca5bf4c643147cafd82bf64304d9b0af6583801d1ec"></script>
<script type="text/javascript">
var SCREEN_WIDTH = 256;
var SCREEN_HEIGHT = 240;
var FRAMEBUFFER_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
var canvas_ctx, image;
var framebuffer_u8, framebuffer_u32;
var AUDIO_BUFFERING = 512;
var SAMPLE_COUNT = 4 * 1024;
var SAMPLE_MASK = SAMPLE_COUNT - 1;
var audio_samples_L = new Float32Array(SAMPLE_COUNT);
var audio_samples_R = new Float32Array(SAMPLE_COUNT);
var audio_write_cursor = 0, audio_read_cursor = 0;
var nes = new jsnes.NES({
onFrame: function (framebuffer_24) {
for (var i = 0; i < FRAMEBUFFER_SIZE; i++) framebuffer_u32[i] = 0xFF000000 | framebuffer_24[i];
},
onAudioSample: function (l, r) {
audio_samples_L[audio_write_cursor] = l;
audio_samples_R[audio_write_cursor] = r;
audio_write_cursor = (audio_write_cursor + 1) & SAMPLE_MASK;
},
});
function onAnimationFrame() {
window.requestAnimationFrame(onAnimationFrame);
image.data.set(framebuffer_u8);
canvas_ctx.putImageData(image, 0, 0);
nes.frame();
}
function audio_remain() {
return (audio_write_cursor - audio_read_cursor) & SAMPLE_MASK;
}
function audio_callback(event) {
var dst = event.outputBuffer;
var len = dst.length;
// Attempt to avoid buffer underruns.
if (audio_remain() < AUDIO_BUFFERING) nes.frame();
var dst_l = dst.getChannelData(0);
var dst_r = dst.getChannelData(1);
for (var i = 0; i < len; i++) {
var src_idx = (audio_read_cursor + i) & SAMPLE_MASK;
dst_l[i] = audio_samples_L[src_idx];
dst_r[i] = audio_samples_R[src_idx];
}
audio_read_cursor = (audio_read_cursor + len) & SAMPLE_MASK;
}
function keyboard(callback, event) {
var player = 1;
switch (event.keyCode) {
case 38: // UP
callback(player, jsnes.Controller.BUTTON_UP); break;
case 40: // Down
callback(player, jsnes.Controller.BUTTON_DOWN); break;
case 37: // Left
callback(player, jsnes.Controller.BUTTON_LEFT); break;
case 39: // Right
callback(player, jsnes.Controller.BUTTON_RIGHT); break;
case 65: // 'a' - qwerty, dvorak
case 81: // 'q' - azerty
callback(player, jsnes.Controller.BUTTON_A); break;
case 83: // 's' - qwerty, azerty
case 79: // 'o' - dvorak
callback(player, jsnes.Controller.BUTTON_B); break;
case 9: // Tab
callback(player, jsnes.Controller.BUTTON_SELECT); break;
case 13: // Return
callback(player, jsnes.Controller.BUTTON_START); break;
default: break;
}
}
function nes_init(canvas_id) {
var canvas = document.getElementById(canvas_id);
canvas_ctx = canvas.getContext("2d");
image = canvas_ctx.getImageData(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
canvas_ctx.fillStyle = "black";
canvas_ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Allocate framebuffer array.
var buffer = new ArrayBuffer(image.data.length);
framebuffer_u8 = new Uint8ClampedArray(buffer);
framebuffer_u32 = new Uint32Array(buffer);
// Setup audio.
var audio_ctx = new window.AudioContext();
var script_processor = audio_ctx.createScriptProcessor(AUDIO_BUFFERING, 0, 2);
script_processor.onaudioprocess = audio_callback;
script_processor.connect(audio_ctx.destination);
}
function nes_boot(rom_data) {
nes.loadROM(rom_data);
window.requestAnimationFrame(onAnimationFrame);
}
function nes_load_data(canvas_id, rom_data) {
nes_init(canvas_id);
nes_boot(rom_data);
}
function nes_load_url(canvas_id, path) {
nes_init(canvas_id);
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);
} else if (this.status === 0) {
// Aborted, so ignore error
} else {
req.onerror();
}
};
req.send();
}
document.addEventListener('keydown', (event) => { keyboard(nes.buttonDown, event) });
document.addEventListener('keyup', (event) => { keyboard(nes.buttonUp, event) });
</script>
<script>window.onload = function () { nes_load_url("nes-canvas", "b://bb6e2e36bc9b7876c60ff2521924dd6051efe9ae4ed9bb6c4fe584cf57b74794"); }</script>
</head>
<body>
<div style="margin: auto; width: 75%;">
<canvas id="nes-canvas" width="256" height="240" style="width: 100%" />
</div>
<p>DPad: Arrow keys<br />Start: Return, Select: Tab<br />A Button: A, B Button: S</p>
</body>
</html> text/htmlutf8
index.html
https://whatsonchain.com/tx/ac4d9a1db60d6fa9f41a372afecab72265c5d1047db6d62b4fbd5731b66e103d