UNPKG

rw-parser

Version:

Parses RenderWare DFF and TXD files into usable format!

186 lines (185 loc) 9.02 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.TxdParser = void 0; var RwFile_1 = require("../RwFile"); var ImageDecoder_1 = require("../utils/ImageDecoder"); var ImageFormatEnums_1 = require("../utils/ImageFormatEnums"); var TxdParser = /** @class */ (function (_super) { __extends(TxdParser, _super); function TxdParser(stream) { return _super.call(this, stream) || this; } TxdParser.prototype.parse = function () { return { textureDictionary: this.readTextureDictionary(), }; }; TxdParser.prototype.readTextureDictionary = function () { this.readSectionHeader(); this.readSectionHeader(); var textureCount = this.readUint16(); this.skip(2); var textureNatives = []; for (var i = 0; i < textureCount; i++) { var textureNative = this.readTextureNative(); textureNatives.push(textureNative); } // Skip unused extension this.skip(this.readSectionHeader().sectionSize); return { textureCount: textureCount, textureNatives: textureNatives }; }; TxdParser.prototype.readTextureNative = function () { this.readSectionHeader(); this.readSectionHeader(); // TODO: Structure this part better // Texture format var platformId = this.readUint32(); var flags = this.readUint32(); var filterMode = (flags & 0xFF); var uAddressing = (flags & 0xF00) >> 8; var vAddressing = (flags & 0xF000) >> 12; var textureName = this.readString(32); var maskName = this.readString(32); // Raster format var rasterFormat = this.readUint32(); var d3dFormat = this.readString(4); var width = this.readUint16(); var height = this.readUint16(); var depth = this.readUint8(); var mipmapCount = this.readUint8(); var rasterType = this.readUint8(); var compressionFlags = this.readUint8(); // Is "dxtType" for III/VC // SA var alpha = (compressionFlags & (1 << 0)) !== 0; var cubeTexture = (compressionFlags & (1 << 1)) !== 0; var autoMipMaps = (compressionFlags & (1 << 2)) !== 0; var compressed = (compressionFlags & (1 << 3)) !== 0; var paletteType = (rasterFormat >> 13) & 3; var mipWidth = width; var mipHeight = height; var mipmaps = []; var palette = (paletteType !== ImageFormatEnums_1.PaletteType.PALETTE_NONE ? this.readPalette(paletteType, depth) : new Uint8Array(0)); for (var i = 0; i < mipmapCount; i++) { var rasterSize = this.readUint32(); var raster = this.read(rasterSize); if (i == 0) { // Raw RGBA presentation var bitmap = void 0; if (palette.length !== 0) { var rasterFormatsWithoutAlpha = [ ImageFormatEnums_1.RasterFormat.RASTER_565, ImageFormatEnums_1.RasterFormat.RASTER_LUM, ImageFormatEnums_1.RasterFormat.RASTER_888, ImageFormatEnums_1.RasterFormat.RASTER_555 ]; var hasAlpha = ((platformId === ImageFormatEnums_1.PlatformType.D3D9 && alpha) || (platformId == ImageFormatEnums_1.PlatformType.D3D8 && !rasterFormatsWithoutAlpha.includes(rasterFormat))); bitmap = Array.from(this.getBitmapWithPalette(paletteType, depth, hasAlpha, raster, palette, width, height)); } else if (platformId === ImageFormatEnums_1.PlatformType.D3D8 && compressionFlags !== 0) { bitmap = Array.from(this.getBitmapWithDXT('DXT' + compressionFlags, raster, width, height)); } else if (platformId === ImageFormatEnums_1.PlatformType.D3D9 && compressed) { bitmap = Array.from(this.getBitmapWithDXT(d3dFormat, raster, width, height)); } else { bitmap = Array.from(this.getBitmapWithRasterFormat(rasterFormat, raster, width, height)); } mipmaps.push(bitmap); } mipWidth /= 2; mipHeight /= 2; } // Skip extension this.skip(this.readSectionHeader().sectionSize); return { platformId: platformId, filterMode: filterMode, uAddressing: uAddressing, vAddressing: vAddressing, textureName: textureName, maskName: maskName, rasterFormat: rasterFormat, d3dFormat: d3dFormat, width: width, height: height, depth: depth, mipmapCount: mipmapCount, rasterType: rasterType, alpha: alpha, cubeTexture: cubeTexture, autoMipMaps: autoMipMaps, compressed: compressed, mipmaps: mipmaps, }; }; TxdParser.prototype.readPalette = function (paletteType, depth) { var size = (paletteType === ImageFormatEnums_1.PaletteType.PALETTE_8 ? 1024 : (depth === 4 ? 64 : 128)); return this.read(size); }; TxdParser.prototype.getBitmapWithPalette = function (paletteType, depth, hasAlpha, raster, palette, width, height) { if (paletteType !== ImageFormatEnums_1.PaletteType.PALETTE_8 && depth == 4) { return (hasAlpha ? ImageDecoder_1.ImageDecoder.pal4(raster, palette, width, height) : ImageDecoder_1.ImageDecoder.pal4NoAlpha(raster, palette, width, height)); } return (hasAlpha ? ImageDecoder_1.ImageDecoder.pal8(raster, palette, width, height) : ImageDecoder_1.ImageDecoder.pal8NoAlpha(raster, palette, width, height)); }; TxdParser.prototype.getBitmapWithDXT = function (dxtType, raster, width, height) { switch (dxtType) { case ImageFormatEnums_1.D3DFormat.D3D_DXT1: return ImageDecoder_1.ImageDecoder.bc1(raster, width, height); case ImageFormatEnums_1.D3DFormat.D3D_DXT2: return ImageDecoder_1.ImageDecoder.bc2(raster, width, height, true); case ImageFormatEnums_1.D3DFormat.D3D_DXT3: return ImageDecoder_1.ImageDecoder.bc2(raster, width, height, false); case ImageFormatEnums_1.D3DFormat.D3D_DXT4: return ImageDecoder_1.ImageDecoder.bc3(raster, width, height, true); case ImageFormatEnums_1.D3DFormat.D3D_DXT5: return ImageDecoder_1.ImageDecoder.bc3(raster, width, height, false); // LUM8_A8 has compressed flag case ImageFormatEnums_1.D3DFormat.D3DFMT_A8L8: return ImageDecoder_1.ImageDecoder.lum8a8(raster, width, height); default: return new Uint8Array(0); } }; TxdParser.prototype.getBitmapWithRasterFormat = function (rasterFormat, raster, width, height) { switch (rasterFormat) { case ImageFormatEnums_1.RasterFormat.RASTER_1555: return ImageDecoder_1.ImageDecoder.bgra1555(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_565: return ImageDecoder_1.ImageDecoder.bgra565(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_4444: return ImageDecoder_1.ImageDecoder.bgra4444(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_LUM: return ImageDecoder_1.ImageDecoder.lum8(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_8888: return ImageDecoder_1.ImageDecoder.bgra8888(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_888: return ImageDecoder_1.ImageDecoder.bgra888(raster, width, height); case ImageFormatEnums_1.RasterFormat.RASTER_555: return ImageDecoder_1.ImageDecoder.bgra555(raster, width, height); default: return new Uint8Array(0); } }; return TxdParser; }(RwFile_1.RwFile)); exports.TxdParser = TxdParser;