mdx-m3-viewer
Version:
A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.
103 lines (85 loc) • 2.72 kB
text/typescript
/**
* A SLK table file.
*/
export default class SlkFile {
rows: (string | number | boolean)[][] = [];
load(buffer: string) {
if (!buffer.startsWith('ID')) {
throw new Error('WrongMagicNumber');
}
let rows = this.rows;
let x = 0;
let y = 0;
for (let line of buffer.split('\n')) {
// The B command is supposed to define the total number of columns and rows, however in UbetSplatData.slk it gives wrong information
// Therefore, just ignore it, since JavaScript arrays grow as they want either way
if (line[0] !== 'B') {
for (let token of line.split(';')) {
let op = token[0];
let valueString = token.substring(1).trim();
let value;
if (op === 'X') {
x = parseInt(valueString, 10) - 1;
} else if (op === 'Y') {
y = parseInt(valueString, 10) - 1;
} else if (op === 'K') {
if (!rows[y]) {
rows[y] = [];
}
if (valueString[0] === '"') {
value = valueString.substring(1, valueString.length - 1);
} else if (valueString === 'TRUE') {
value = true;
} else if (valueString === 'FALSE') {
value = false;
} else {
value = parseFloat(valueString);
if (isNaN(value)) {
value = valueString;
}
}
rows[y][x] = value;
}
}
}
}
}
save() {
let rows = this.rows;
let rowCount = rows.length;
let lines = [];
let biggestColumn = 0;
for (let y = 0; y < rowCount; y++) {
let row = rows[y];
let columnCount = row.length;
if (columnCount > biggestColumn) {
biggestColumn = columnCount;
}
let firstOfRow = true;
for (let x = 0; x < columnCount; x++) {
let value = row[x];
if (value !== undefined) {
let encoded;
if (typeof value === 'string') {
encoded = `"${value}"`;
} else if (typeof value === 'boolean') {
if (value) {
encoded = 'TRUE';
} else {
encoded = 'FALSE';
}
} else {
encoded = `${value}`;
}
if (firstOfRow) {
firstOfRow = false;
lines.push(`C;X${x + 1};Y${y + 1};K${encoded}`);
} else {
lines.push(`C;X${x + 1};K${encoded}`);
}
}
}
}
return `ID;P\r\nB;X${biggestColumn};Y${rowCount}\r\n${lines.join('\r\n')}\r\nE`;
}
}