You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.8 KiB
JavaScript

// import { base64decode, base64encode, base64ToBytes } from './base64.js';
// https://github.com/nesbox/TIC-80/wiki/TIC-File-Format
export const CHUNK_TILES = 1,
CHUNK_SPRITES = 2,
CHUNK_COVER = 3,
CHUNK_MAP = 4,
CHUNK_CODE = 5,
CHUNK_FLAGS = 6,
CHUNK_SAMPLES = 9,
CHUNK_WAVEFORM = 10,
CHUNK_PALETTE = 12,
CHUNK_MUSIC_TRACKS = 14,
CHUNK_MUSIC_PATTERNS = 15,
CHUNK_CODE_ZIP = 16,
LITTLE_ENDIAN = 1;
function pad0(n, p) {
n = ''+n;
while (n.length < p) { n = '0'+n; }
return n;
}
function tohex (a) {
let ret = '', hh;
console.log("tohex", a);
for (var b=0, len=a.byteLength; b<len; b+=1) {
ret += pad0(a.getUint8(b).toString(16), 2);
}
return ret;
}
export function parsetic (buffer) {
var ret = {},
data = new DataView(buffer),
i=0,
bank,
ctype,
clen,
future_use,
firstbyte;
ret.chunks = [];
ret.chunks_by_type = {};
while (i<data.byteLength) {
firstbyte = data.getUint8(i, LITTLE_ENDIAN);
bank = firstbyte >> 5;
ctype = firstbyte & 0b11111;
i+=1;
clen = data.getUint16(i, LITTLE_ENDIAN);
i+=2;
future_use = data.getUint8(i, LITTLE_ENDIAN);
i+=1; // byte reserved for future_use
var chunk = {bank: bank, ctype: ctype, future_use: future_use};
chunk.original_length = clen; // can be out of sync with data, only for control purposes
ret.chunks.push(chunk);
ret.chunks_by_type[ctype] = chunk;
var chunk_data = buffer.slice(i, i+clen);
if (ctype == CHUNK_CODE) {
ret.code = chunk;
chunk.text = new TextDecoder().decode(chunk_data);
} else {
//chunk.data = new DataView(buf.buffer, i, clen);
chunk.data = chunk_data;
}
i += clen;
// chunk.data = base64encode(chunk.data);
}
ret.tobuffer = function () {
// dry run for length
var outputLength = 0;
ret.chunks.forEach(chunk => {
outputLength += 4;
outputLength += (chunk.text) ? new TextEncoder().encode(chunk.text).byteLength : chunk.data.byteLength;
});
var outputBuffer = new Uint8Array(outputLength),
o = 0,
data = new DataView(outputBuffer.buffer);
ret.chunks.forEach(chunk => {
data.setUint8(o++, (chunk.bank << 5) | chunk.ctype);
var chunk_data = chunk.text ? new TextEncoder().encode(chunk.text) : chunk.data;
data.setUint16(o, chunk_data.byteLength, 1);
o += 2;
data.setUint8(o++, chunk.future_use);
for (var i=0; i<chunk_data.byteLength; i++) {
data.setUint8(o++, chunk_data[i]);
}
});
return outputBuffer;
};
return ret;
}