Skip to content

Commit

Permalink
Refactor the RLE compression of Serialiser 🗜️.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarty committed Oct 5, 2024
1 parent cf0d7de commit ae6be81
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 40 deletions.
35 changes: 35 additions & 0 deletions src/lib/serialiser/Serialiser.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,41 @@ class Serialiser {
}
}

// Compress an array of data using the RLE compression algorithm.
compressArray(data) {
let n = 0;
while (n < data.length) {
let initialValue = data[n];
let loop = 0;

// Look 2 tiles ahead.
if (data[n] !== data[n + 1] || data[n] !== data[n + 2]) {
// The next 3 tiles are different. Count how many unique tiles there are.
// It stops once it encounters 3 identical tiles in a row.
const initialN = n;

do {
loop++;
initialValue = data[++n];
} while (initialValue !== data[n + 1] || initialValue !== data[n + 2]);

this.setUint8(loop | 0x80); // Set the type of loop.
for (let i = initialN; i < n; i++) {
this.setUint8(data[i]);
}
} else {
// The next 3 tiles are identical. Count how many of them in a row.
// It stops when it finds a different tile.
do {
loop++;
} while (initialValue === data[++n]);

this.setUint8(loop);
this.setUint8(initialValue);
}
}
}

// Firefox doesn't support ArrayBuffer#resize.
#resize(newByteLength) {
if (ArrayBuffer.prototype.resize) {
Expand Down
3 changes: 1 addition & 2 deletions src/lib/serialiser/room/serialiseRoomAttributes.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import Serialiser from '../Serialiser.js';
import { compress } from '../serialiserUtils.js';

const serialiseRoomAttributes = (attributes = [], width = 0) => {
const serialiser = new Serialiser();

const lineWidth = (width + 4) / 4; // 16 for 60px rooms, 8 for 28px rooms.
for (let i = 0; i < 4; i++) {
compress(serialiser, attributes.slice(i * 16, i * 16 + lineWidth));
serialiser.compressArray(attributes.slice(i * 16, i * 16 + lineWidth));
}

return serialiser.buffer;
Expand Down
3 changes: 1 addition & 2 deletions src/lib/serialiser/room/serialiseRoomNametable.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import Serialiser from '../Serialiser.js';
import { compress } from '../serialiserUtils.js';

const serialiseRoomNametable = (nametable = []) => {
const serialiser = new Serialiser();

for (let i = 0; i < nametable.length; i++) {
compress(serialiser, nametable[i].slice(2, 62));
serialiser.compressArray(nametable[i].slice(2, 62));
}

return serialiser.buffer;
Expand Down
36 changes: 0 additions & 36 deletions src/lib/serialiser/serialiserUtils.js

This file was deleted.

0 comments on commit ae6be81

Please sign in to comment.