using SanAndreasUnity.Utilities; using System; using System.IO; namespace SanAndreasUnity.Importing.RenderWareStream { [SectionType(21)] public class TextureNative : SectionData { public readonly UInt32 PlatformID; public readonly Filter FilterFlags; public readonly WrapMode WrapV; public readonly WrapMode WrapU; public readonly string DiffuseName; public readonly string AlphaName; public readonly RasterFormat Format; public readonly bool Alpha; public readonly CompressionMode Compression; public readonly UInt16 Width; public readonly UInt16 Height; public readonly byte BPP; public readonly byte MipMapCount; public readonly byte RasterType; public readonly Int32 ImageDataSize; public readonly byte[] ImageData; public readonly byte[] ImageLevelData; public TextureNative(SectionHeader header, Stream stream) : base(header, stream) { SectionHeader.Read(stream); var reader = new BinaryReader(stream); PlatformID = reader.ReadUInt32(); FilterFlags = (Filter)reader.ReadUInt16(); WrapV = (WrapMode)reader.ReadByte(); WrapU = (WrapMode)reader.ReadByte(); DiffuseName = reader.ReadString(32); AlphaName = reader.ReadString(32); Format = (RasterFormat)reader.ReadUInt32(); if (PlatformID == 9) { var dxt = reader.ReadString(4); switch (dxt) { case "DXT1": Compression = CompressionMode.DXT1; break; case "DXT3": Compression = CompressionMode.DXT3; break; default: Compression = CompressionMode.None; break; } } else { Alpha = reader.ReadUInt32() == 0x1; } Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); BPP = (byte)(reader.ReadByte() >> 3); MipMapCount = reader.ReadByte(); RasterType = reader.ReadByte(); if (RasterType != 0x4) { throw new Exception("Unexpected RasterType, expected 0x04."); } if (PlatformID == 9) { Alpha = (reader.ReadByte() & 0x1) == 0x1; } else { Compression = (CompressionMode)reader.ReadByte(); } ImageDataSize = reader.ReadInt32(); ImageData = reader.ReadBytes(ImageDataSize); if ((Format & RasterFormat.ExtMipMap) != 0) { var tot = ImageDataSize; for (var i = 0; i < MipMapCount; ++i) { tot += ImageDataSize >> (2 * i); } ImageLevelData = reader.ReadBytes(tot); } else { ImageLevelData = ImageData; } } } }