arx-convert
Version:
Converts various Arx Fatalis formats to JSON or YAML and back
314 lines • 9.13 kB
JavaScript
import { LITTLE_ENDIAN, TRUNCATE_ZERO_BYTES, KEEP_ZERO_BYTES, BYTE_OF_AN_UNKNOWN_CHAR } from './constants.js';
import { decodeText, encodeText, repeat } from './helpers.js';
export class BinaryIO extends DataView {
static sizeOfFloat32() {
return 4;
}
static sizeOfFloat32Array(length) {
return length * BinaryIO.sizeOfFloat32();
}
static sizeOfInt8() {
return 1;
}
static sizeOfInt8Array(length) {
return length * BinaryIO.sizeOfInt8();
}
static sizeOfInt16() {
return 2;
}
static sizeOfInt16Array(length) {
return length * BinaryIO.sizeOfInt16();
}
static sizeOfInt32() {
return 4;
}
static sizeOfInt32Array(length) {
return length * BinaryIO.sizeOfInt32();
}
static sizeOfUint8() {
return 1;
}
static sizeOfUint8Array(length) {
return length * BinaryIO.sizeOfUint8();
}
static sizeOfUint16() {
return 2;
}
static sizeOfUint16Array(length) {
return length * BinaryIO.sizeOfUint16();
}
static sizeOfUint32() {
return 4;
}
static sizeOfUint32Array(length) {
return length * BinaryIO.sizeOfUint32();
}
static sizeOfString(length) {
return length;
}
static sizeOfNullTerminatedString(str) {
return str.length + 1;
}
static sizeOfVector3() {
return BinaryIO.sizeOfFloat32Array(3);
}
static sizeOfVector3Array(length) {
return length * BinaryIO.sizeOfVector3();
}
static sizeOfRotation() {
return BinaryIO.sizeOfFloat32Array(3);
}
static sizeOfQuat() {
return BinaryIO.sizeOfFloat32Array(4);
}
position;
constructor(buffer, byteOffset, byteLength) {
super(buffer, byteOffset, byteLength);
this.position = 0;
}
readFloat32() {
const val = this.getFloat32(this.position, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfFloat32();
return val;
}
readFloat32Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readFloat32());
}
return arr;
}
readInt8() {
const val = this.getInt8(this.position);
this.position = this.position + BinaryIO.sizeOfInt8();
return val;
}
readInt8Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readInt8());
}
return arr;
}
readInt16() {
const val = this.getInt16(this.position, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfInt16();
return val;
}
readInt16Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readInt16());
}
return arr;
}
readInt32() {
const val = this.getInt32(this.position, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfInt32();
return val;
}
readInt32Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readInt32());
}
return arr;
}
readUint8() {
const val = this.getUint8(this.position);
this.position = this.position + BinaryIO.sizeOfUint8();
return val;
}
readUint8Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readUint8());
}
return arr;
}
readUint16() {
const val = this.getUint16(this.position, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfUint16();
return val;
}
readUint16Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readUint16());
}
return arr;
}
readUint32() {
const val = this.getUint32(this.position, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfUint32();
return val;
}
readUint32Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readUint32());
}
return arr;
}
writeFloat32(value) {
this.setFloat32(this.position, value, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfFloat32();
}
writeFloat32Array(values) {
values.forEach((value) => {
this.writeFloat32(value);
});
}
writeInt8(value) {
this.setInt8(this.position, value);
this.position = this.position + BinaryIO.sizeOfInt8();
}
writeInt8Array(values) {
values.forEach((value) => {
this.writeInt8(value);
});
}
writeInt16(value) {
this.setInt16(this.position, value, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfInt16();
}
writeInt16Array(values) {
values.forEach((value) => {
this.writeInt16(value);
});
}
writeInt32(value) {
this.setInt32(this.position, value, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfInt32();
}
writeInt32Array(values) {
values.forEach((value) => {
this.writeInt32(value);
});
}
writeUint8(value) {
this.setUint8(this.position, value);
this.position = this.position + BinaryIO.sizeOfUint8();
}
writeUint8Array(values) {
if (Array.isArray(values)) {
values.forEach((value) => {
this.writeUint8(value);
});
}
else {
new Uint8Array(values).forEach((value) => {
this.writeUint8(value);
});
}
}
writeUint16(value) {
this.setUint16(this.position, value, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfUint16();
}
writeUint16Array(values) {
values.forEach((value) => {
this.writeUint16(value);
});
}
writeUint32(value) {
this.setUint32(this.position, value, LITTLE_ENDIAN);
this.position = this.position + BinaryIO.sizeOfUint32();
}
writeUint32Array(values) {
values.forEach((value) => {
this.writeUint32(value);
});
}
readString(length, truncateZeroBytes = TRUNCATE_ZERO_BYTES) {
const codes = [];
if (length === undefined) {
let c = this.readUint8();
while (c !== 0) {
codes.push(c);
c = this.readUint8();
}
}
else {
let gotNil = false;
for (let i = 0; i < length; i++) {
const c = this.readUint8();
if (gotNil && truncateZeroBytes === TRUNCATE_ZERO_BYTES) {
continue;
}
if (c === 0) {
gotNil = true;
}
if (c !== 0 || truncateZeroBytes === KEEP_ZERO_BYTES) {
if (c === 0) {
codes.push(BYTE_OF_AN_UNKNOWN_CHAR);
}
else {
codes.push(c);
}
}
}
}
return decodeText(codes);
}
writeString(str, length) {
// if length is given we assume a fixed length string
if (length === undefined) {
// otherwise it's a 0 terminated c string
encodeText(str).forEach((charCode) => {
this.writeUint8(charCode);
});
this.writeUint8(0);
}
else {
const charCodes = repeat(0, length);
// replacing 0s in charCodes one by one from left to right
encodeText(str).forEach((charCode, index) => {
charCodes[index] = charCode;
});
charCodes.forEach((charCode) => {
this.writeUint8(charCode);
});
}
}
readVector3() {
const [x, y, z] = this.readFloat32Array(3);
return { x, y, z };
}
readVector3Array(length) {
const arr = [];
for (let i = 0; i < length; i++) {
arr.push(this.readVector3());
}
return arr;
}
writeVector3({ x, y, z }) {
this.writeFloat32Array([x, y, z]);
}
writeVector3Array(values) {
values.forEach((value) => {
this.writeVector3(value);
});
}
readRotation() {
const [a, b, g] = this.readFloat32Array(3);
return { a, b, g };
}
writeRotation({ a, b, g }) {
this.writeFloat32Array([a, b, g]);
}
readQuat() {
const [w, x, y, z] = this.readFloat32Array(4);
return { x, y, z, w };
}
writeQuat({ x, y, z, w }) {
this.writeFloat32Array([w, x, y, z]);
}
writeBuffer(buffer) {
this.writeUint8Array(buffer);
}
skipBytes(numberOfBytes) {
this.position = this.position + numberOfBytes;
}
}
//# sourceMappingURL=BinaryIO.js.map