constructor() {
this._tiles = 0;
this._lastsubencoding = 0;
+ this._tileBuffer = new Uint8Array(16 * 16 * 4);
}
decodeRect(x, y, width, height, sock, display, depth) {
rQi += 4;
}
- display.startTile(tx, ty, tw, th, this._background);
+ this._startTile(tx, ty, tw, th, this._background);
if (subencoding & 0x08) { // AnySubrects
let subrects = rQ[rQi];
rQi++;
const sw = (wh >> 4) + 1;
const sh = (wh & 0x0f) + 1;
- display.subTile(sx, sy, sw, sh, color);
+ this._subTile(sx, sy, sw, sh, color);
}
}
- display.finishTile();
+ this._finishTile(display);
}
sock.rQi = rQi;
this._lastsubencoding = subencoding;
return true;
}
+
+ // start updating a tile
+ _startTile(x, y, width, height, color) {
+ this._tileX = x;
+ this._tileY = y;
+ this._tileW = width;
+ this._tileH = height;
+
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+
+ const data = this._tileBuffer;
+ for (let i = 0; i < width * height * 4; i += 4) {
+ data[i] = blue;
+ data[i + 1] = green;
+ data[i + 2] = red;
+ data[i + 3] = 255;
+ }
+ }
+
+ // update sub-rectangle of the current tile
+ _subTile(x, y, w, h, color) {
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+ const xend = x + w;
+ const yend = y + h;
+
+ const data = this._tileBuffer;
+ const width = this._tileW;
+ for (let j = y; j < yend; j++) {
+ for (let i = x; i < xend; i++) {
+ const p = (i + (j * width)) * 4;
+ data[p] = blue;
+ data[p + 1] = green;
+ data[p + 2] = red;
+ data[p + 3] = 255;
+ }
+ }
+ }
+
+ // draw the current tile to the screen
+ _finishTile(display) {
+ display.blitImage(this._tileX, this._tileY,
+ this._tileW, this._tileH,
+ this._tileBuffer, 0);
+ }
}
this._fbHeight = 0;
this._prevDrawStyle = "";
- this._tile = null;
- this._tile16x16 = null;
- this._tileX = 0;
- this._tileY = 0;
Log.Debug(">> Display.constructor");
throw new Error("Canvas does not support createImageData");
}
- this._tile16x16 = this._drawCtx.createImageData(16, 16);
Log.Debug("<< Display.constructor");
// ===== PROPERTIES =====
});
}
- // start updating a tile
- startTile(x, y, width, height, color) {
- this._tileX = x;
- this._tileY = y;
- if (width === 16 && height === 16) {
- this._tile = this._tile16x16;
- } else {
- this._tile = this._drawCtx.createImageData(width, height);
- }
-
- const red = color[2];
- const green = color[1];
- const blue = color[0];
-
- const data = this._tile.data;
- for (let i = 0; i < width * height * 4; i += 4) {
- data[i] = red;
- data[i + 1] = green;
- data[i + 2] = blue;
- data[i + 3] = 255;
- }
- }
-
- // update sub-rectangle of the current tile
- subTile(x, y, w, h, color) {
- const red = color[2];
- const green = color[1];
- const blue = color[0];
- const xend = x + w;
- const yend = y + h;
-
- const data = this._tile.data;
- const width = this._tile.width;
- for (let j = y; j < yend; j++) {
- for (let i = x; i < xend; i++) {
- const p = (i + (j * width)) * 4;
- data[p] = red;
- data[p + 1] = green;
- data[p + 2] = blue;
- data[p + 3] = 255;
- }
- }
- }
-
- // draw the current tile to the screen
- finishTile() {
- this._drawCtx.putImageData(this._tile, this._tileX, this._tileY);
- this._damage(this._tileX, this._tileY,
- this._tile.width, this._tile.height);
- }
-
blitImage(x, y, width, height, arr, offset, fromQueue) {
if (this._renderQ.length !== 0 && !fromQueue) {
// NB(directxman12): it's technically more performant here to use preallocated arrays,
| fillRect | (x, y, width, height, color, from_queue) | Draw a filled in rectangle
| copyImage | (old_x, old_y, new_x, new_y, width, height, from_queue) | Copy a rectangular area
| imageRect | (x, y, width, height, mime, arr) | Draw a rectangle with an image
-| startTile | (x, y, width, height, color) | Begin updating a tile
-| subTile | (tile, x, y, w, h, color) | Update a sub-rectangle within the given tile
-| finishTile | () | Draw the current tile to the display
| blitImage | (x, y, width, height, arr, offset, from_queue) | Blit pixels (of R,G,B,A) to the display
| blitRgbImage | (x, y, width, height, arr, offset, from_queue) | Blit RGB encoded image to display
| blitRgbxImage | (x, y, width, height, arr, offset, from_queue) | Blit RGBX encoded image to display
display.flush();
});
- it('should support drawing tile data with a background color and sub tiles', function () {
- display.startTile(0, 0, 4, 4, [0, 0xff, 0]);
- display.subTile(0, 0, 2, 2, [0xff, 0, 0]);
- display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
- display.finishTile();
- display.flip();
- expect(display).to.have.displayed(checkedData);
- });
-
- // We have a special cache for 16x16 tiles that we need to test
- it('should support drawing a 16x16 tile', function () {
- const largeCheckedData = new Uint8Array(16*16*4);
- display.resize(16, 16);
-
- for (let y = 0;y < 16;y++) {
- for (let x = 0;x < 16;x++) {
- let pixel;
- if ((x < 4) && (y < 4)) {
- // NB: of course IE11 doesn't support #slice on ArrayBufferViews...
- pixel = Array.prototype.slice.call(checkedData, (y*4+x)*4, (y*4+x+1)*4);
- } else {
- pixel = [0, 0xff, 0, 255];
- }
- largeCheckedData.set(pixel, (y*16+x)*4);
- }
- }
-
- display.startTile(0, 0, 16, 16, [0, 0xff, 0]);
- display.subTile(0, 0, 2, 2, [0xff, 0, 0]);
- display.subTile(2, 2, 2, 2, [0xff, 0, 0]);
- display.finishTile();
- display.flip();
- expect(display).to.have.displayed(largeCheckedData);
- });
-
it('should support drawing BGRX blit images with true color via #blitImage', function () {
const data = [];
for (let i = 0; i < 16; i++) {