rw-img-reader
Version:
Grand Theft Auto(III, VC, SA) img-archive reader
43 lines (42 loc) • 1.5 kB
JavaScript
// Based on https://github.com/magcius/noclip.website/blob/main/src/GrandTheftAuto3/tools/extractor.ts
export class ImgReader {
constructor() {
this.assets = [];
this.img = new ArrayBuffer;
}
UTF8ToString(array) {
let length = 0;
while (length < array.length && array[length]) {
length++;
}
return (new TextDecoder()).decode(array.subarray(0, length));
}
loadDIR(buf) {
let assets = [];
let view = new DataView(buf);
let byteLength = buf.byteLength;
// if "VER2" - in fist 4 bytes => this is SA .img archive
const isSa = ('VER2' === this.UTF8ToString(new Uint8Array(buf, 0, 4)));
if (isSa) {
// second 4 bytes - Number Of Entries in archive
byteLength = (32 * view.getUint32(4, true)) + 8;
}
// in SA: 4 bytes = "VER2" + 4 bytes = Number Of Entries
for (let i = (isSa ? 8 : 0); i < byteLength; i += 32) {
const offset = view.getUint32(i, true);
const size = view.getUint32(i + 4, true);
const name = this.UTF8ToString(new Uint8Array(buf, i + 8, 24));
assets.push({ offset, size, name });
}
this.assets = assets;
}
loadIMG(imgFileBuffer) {
this.img = imgFileBuffer;
}
getAssetList() {
return this.assets;
}
loadAsset(asset) {
return this.img.slice(2048 * asset.offset, 2048 * (asset.offset + asset.size));
}
}