mirror of
https://github.com/google/pebble.git
synced 2025-03-15 08:41:21 +00:00
83 lines
2.8 KiB
JavaScript
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);
|
|
}
|