pebble/applib-targets/emscripten/html-binding.js
2025-01-27 11:38:16 -08:00

83 lines
2.8 KiB
JavaScript

/*
Copyright © 2015-2016 Pebble Technology Corp.,
All Rights Reserved. http://pebble.github.io/rockyjs/LICENSE
This describes functionality to bind the Rocky Simulator to an HTML canvas
element. This file is included into the Emscripten output using --post-js,
as such it will end up in body of the RockySimulator(options) constructor.
*/
if (typeof(Module) === 'undefined') {
var Module = {};
}
Module.bindCanvas = function(canvas) {
// in a future version, these values should adapt automatically
// also, we want the ability to create framebuffers of larger sizes
var canvasW = canvas.width;
var canvasH = canvas.height;
var framebufferW = 144;
var framebufferH = 168;
// scale gives us the ability to do a nearest-neighbor scaling
var scale = options.scale ||
Math.min(canvasW / framebufferW, canvasH / framebufferH);
// pixel access to read (framebuffer) and write to (canvas)
var canvasCtx = canvas.getContext('2d');
var canvasPixelData = canvasCtx.createImageData(canvasW, canvasH);
var canvasPixels = canvasPixelData.data;
var framebufferPixelPTR = Module.ccall(
'emx_graphics_get_pixels', 'number', []
);
var isRenderRequested = false;
var copyFrameBufferToCanvas = function(timestamp) {
console.log('copying pixels...');
isRenderRequested = false;
var framebufferPixels = new Uint8Array(Module.HEAPU8.buffer,
framebufferPixelPTR,
framebufferW * framebufferH);
// renders current state of the framebuffer to the bound canvas
// respecting the passed scale
for (var y = 0; y < canvasH; y++) {
var pebbleY = (y / scale) >> 0;
if (pebbleY >= framebufferH) {
break;
}
for (var x = 0; x < canvasW; x++) {
var pebbleX = (x / scale) >> 0;
if (pebbleX >= framebufferW) {
break;
}
var pebbleOffset = pebbleY * framebufferW + pebbleX;
var in_values = framebufferPixels[pebbleOffset];
var r = ((in_values >> 4) & 0x3) * 85;
var g = ((in_values >> 2) & 0x3) * 85;
var b = ((in_values >> 0) & 0x3) * 85;
var canvasOffset = (y * canvasW + x) * 4;
canvasPixels[canvasOffset + 0] = r;
canvasPixels[canvasOffset + 1] = g;
canvasPixels[canvasOffset + 2] = b;
canvasPixels[canvasOffset + 3] = 255;
}
}
canvasCtx.putImageData(canvasPixelData, 0, 0);
};
Module.frameBufferMarkDirty = function() {
if (isRenderRequested) {
return;
}
console.log('request render');
isRenderRequested = true;
window.requestAnimationFrame(copyFrameBufferToCanvas);
}
};
// Apply `options` from the RockySimulator(options) constructor:
if (typeof(options) !== 'undefined' && options.canvas) {
Module.bindCanvas(options.canvas);
}