Skip to content

Commit d6f5f55

Browse files
author
kirjavascript
committed
make compression threaded
1 parent 3d68dd2 commit d6f5f55

File tree

19 files changed

+11273
-2558
lines changed

19 files changed

+11273
-2558
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
## [unreleased]
44
- Change DPLC limit to 255
5+
- Make (de)compression threaded
56
- Fix issue where image data would be cached incorrectly
7+
- Electron updated to v26
68

79
## [1.2.2]
810
- Added sprite rotation algorithm: 3 shears

TODO

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
/* https://raw.githubusercontent.com/Dandaman955/Streets-of-Rage-1-Disassembly-Redux/master/SoR.asm */
1111
/* http://info.sonicretro.org/Disassemblies */
1212

13+
14+
macros for mappings
15+
format hooks for defining asm output
16+
define macro files in script??
17+
18+
return rotsprite
19+
1320
ROADMAP
1421
look at issues related to crashes
1522
drawing mode bugs
@@ -31,7 +38,6 @@ pink surrounding tiles sometimes breaks
3138

3239
FEATURES
3340
set colour of art tiles
34-
make decompression threaded
3541
ctrl+wheel for horiz scroll
3642
==
3743
select multiple sprites at once to reorder

app/components/file/file-object.js

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
writeBIN,
99
writeASM,
1010
} from '#formats/scripts';
11-
import { compressionFormats } from '#formats/compression';
11+
import { decompress, compress, compressionFormats } from '#formats/compression';
1212
import { bufferToTiles, tilesToBuffer } from '#formats/art';
1313
import { buffersToColors, colorsToBuffers } from '#formats/palette';
1414
import { environment } from '#store/environment';
@@ -37,7 +37,7 @@ export const FileObject = observer(({ obj }) => {
3737
const scriptArt = scriptSafe && script.art;
3838
const scriptPalettes = scriptSafe && script.palettes;
3939
const toggleDPLCs = () => (obj.dplcs.enabled = !obj.dplcs.enabled);
40-
const parseASM = ((scriptSafe && script.parseASM) || parseASMInternal);
40+
const parseASM = (scriptSafe && script.parseASM) || parseASMInternal;
4141

4242
function ioWrap(filePath, setError, e, cb) {
4343
setError();
@@ -83,10 +83,16 @@ export const FileObject = observer(({ obj }) => {
8383
function loadArt(e) {
8484
ioWrap(obj.art.path, setArtError, e, async (path) => {
8585
const buffer = (await fs.readFile(path)).slice(obj.art.offset || 0);
86-
const tiles = scriptArt
87-
? script.readArt(buffer)
88-
: bufferToTiles(buffer, obj.art.compression);
89-
environment.tiles.replace(tiles);
86+
87+
if (scriptArt) {
88+
environment.tiles.replace(script.readArt(buffer));
89+
} else {
90+
const decompBuffer = await decompress(
91+
buffer,
92+
obj.art.compression,
93+
);
94+
environment.tiles.replace(bufferToTiles(decompBuffer));
95+
}
9096
});
9197
}
9298

@@ -99,6 +105,16 @@ export const FileObject = observer(({ obj }) => {
99105
? script.writeArt(tiles)
100106
: tilesToBuffer(environment.tiles, obj.art.compression);
101107
await fs.writeFile(path, tiles);
108+
109+
if (scriptArt) {
110+
await fs.writeFile(path, script.writeArt(tiles));
111+
} else {
112+
const buffer = tilesToBuffer(environment.tiles);
113+
await fs.writeFile(
114+
path,
115+
Buffer.from(await compress(buffer, obj.art.compression)),
116+
);
117+
}
102118
});
103119
}
104120

@@ -214,13 +230,9 @@ export const FileObject = observer(({ obj }) => {
214230
? palPath
215231
: workspace.absolutePath(palPath);
216232

217-
const chunk = (scriptPalettes
218-
? script.writePalettes
219-
: colorsToBuffers)(
220-
environment.palettes,
221-
cursor,
222-
cursor + length,
223-
);
233+
const chunk = (
234+
scriptPalettes ? script.writePalettes : colorsToBuffers
235+
)(environment.palettes, cursor, cursor + length);
224236
await fs.writeFile(path, chunk);
225237
cursor += length;
226238
}

app/formats/art.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
import { decompress, compress } from '#formats/compression';
21
import flattenDeep from 'lodash/flattenDeep';
32
import chunk from 'lodash/chunk';
43
import { toJS } from 'mobx';
54

65
// a duxel is two pixels / a byte
76

8-
export function bufferToTiles(buffer, compression) {
7+
export function bufferToTiles(buffer) {
98
let tiles = [];
10-
const data = decompress(buffer, compression);
11-
12-
const tileQty = data.length/0x20;
9+
const tileQty = buffer.length/0x20;
1310

1411
for (let i = 0; i < tileQty; i++) {
1512
let pixels = [];
1613
for (let duoIndex = 0; duoIndex < 0x20; duoIndex++) {
17-
let duxel = data[(0x20 * i) + duoIndex];
14+
let duxel = buffer[(0x20 * i) + duoIndex];
1815
pixels.push(duxel >> 4, duxel & 0xF);
1916
}
2017
tiles.push(pixels);
@@ -23,7 +20,7 @@ export function bufferToTiles(buffer, compression) {
2320
return tiles;
2421
}
2522

26-
export function tilesToBuffer(tiles, compression) {
23+
export function tilesToBuffer(tiles) {
2724

2825
const pixels = flattenDeep(toJS(tiles));
2926

@@ -32,5 +29,5 @@ export function tilesToBuffer(tiles, compression) {
3229
(H << 4) + L
3330
));
3431

35-
return Buffer.from(compress(Uint8Array.from(duxels), compression));
32+
return Uint8Array.from(duxels);
3633
}

app/formats/compression-worker.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as Comlink from 'comlink';
2+
3+
self.Module = {
4+
locateFile: url => `../wasm/${url}`,
5+
};
6+
7+
importScripts('../wasm/mdcomp_portable.js');
8+
9+
function mdcomp(func, data) {
10+
const operation = Module[func];
11+
const sp = Module.stackSave();
12+
try {
13+
const dataPtr = _malloc(data.length);
14+
try {
15+
writeArrayToMemory(data, dataPtr);
16+
const outputPtrPtr = Module.stackAlloc(4);
17+
const outputSizePtr = Module.stackAlloc(4);
18+
if (operation(dataPtr, data.length, outputPtrPtr, outputSizePtr)) {
19+
const outputPtr = HEAP32[outputPtrPtr >> 2];
20+
try {
21+
const outputSize = HEAP32[outputSizePtr >> 2];
22+
const output = new Uint8Array(outputSize);
23+
let outputBuffer = outputPtr;
24+
for (let i=0; i < outputSize; i++) {
25+
output[i] = HEAP8[outputBuffer++];
26+
}
27+
return output;
28+
} finally {
29+
_free(outputPtr);
30+
}
31+
}
32+
} finally {
33+
_free(dataPtr);
34+
}
35+
} finally {
36+
Module.stackRestore(sp);
37+
}
38+
};
39+
40+
Comlink.expose({ mdcomp });

app/formats/compression.js

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as Comlink from 'comlink';
2+
13
export const compressionFormats = {
24
'Uncompressed': undefined,
35
'Nemesis': 'nemesis',
@@ -12,49 +14,19 @@ export const compressionFormats = {
1214
'RLE': 'snkrle',
1315
};
1416

15-
export function decompress(buffer, compression) {
17+
const worker = Comlink.wrap(new Worker('bundles/compression-worker.js'));
18+
19+
export async function decompress(buffer, compression) {
1620
const operation = compressionFormats[compression];
1721

1822
if (!operation) return new Uint8Array(buffer);
19-
else return mdcomp(`_${operation}_decode`, buffer);
23+
else return await worker.mdcomp(`_${operation}_decode`, buffer);
2024

2125
}
2226

23-
export function compress(buffer, compression) {
27+
export async function compress(buffer, compression) {
2428
const operation = compressionFormats[compression];
2529

2630
if (!operation) return buffer;
27-
else return mdcomp(`_${operation}_encode`, buffer);
28-
}
29-
30-
31-
function mdcomp(func, data) {
32-
const operation = Module[func];
33-
const sp = Module.stackSave();
34-
try {
35-
const dataPtr = _malloc(data.length);
36-
try {
37-
writeArrayToMemory(data, dataPtr);
38-
const outputPtrPtr = Module.stackAlloc(4);
39-
const outputSizePtr = Module.stackAlloc(4);
40-
if (operation(dataPtr, data.length, outputPtrPtr, outputSizePtr)) {
41-
const outputPtr = HEAP32[outputPtrPtr >> 2];
42-
try {
43-
const outputSize = HEAP32[outputSizePtr >> 2];
44-
const output = new Uint8Array(outputSize);
45-
let outputBuffer = outputPtr;
46-
for (let i=0; i < outputSize; i++) {
47-
output[i] = HEAP8[outputBuffer++];
48-
}
49-
return output;
50-
} finally {
51-
_free(outputPtr);
52-
}
53-
}
54-
} finally {
55-
_free(dataPtr);
56-
}
57-
} finally {
58-
Module.stackRestore(sp);
59-
}
31+
else return await worker.mdcomp(`_${operation}_encode`, buffer);
6032
}

development/build.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@ const esbuild = require('esbuild');
33
const path = require('path');
44

55
module.exports = (mainWindow) => {
6-
const { writeFile, unlinkSync, existsSync } = fs;
6+
const { writeFile, rmSync, readdirSync } = fs;
77

88
mainWindow?.openDevTools();
9-
if (existsSync('./static/bundles/main.js')) {
10-
unlinkSync('./static/bundles/main.js');
11-
}
9+
10+
const outdir = './static/bundles';
11+
readdirSync(outdir).forEach((f) => rmSync(`${outdir}/${f}`));
1212

1313
const devMode = !!mainWindow;
1414

1515
esbuild
1616
.build({
17-
entryPoints: ['./app/main.js'],
18-
outdir: './static/bundles',
17+
outdir,
18+
entryPoints: {
19+
main: './app/main.js',
20+
'compression-worker': './app/formats/compression-worker.js',
21+
},
1922
bundle: true,
2023
watch: devMode,
2124
sourcemap: devMode,

0 commit comments

Comments
 (0)