using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CodeWalker.GameFiles { [TypeConverter(typeof(ExpandableObjectConverter))] public class TextureDictionary : ResourceFileBase { public override long BlockLength { get { return 64; } } // structure data public uint Unknown_10h { get; set; } // 0x00000000 public uint Unknown_14h { get; set; } // 0x00000000 public uint Unknown_18h { get; set; } // 0x00000001 public uint Unknown_1Ch { get; set; } // 0x00000000 public ResourceSimpleList64Ptr TextureNameHashesPtr { get; set; } public uint[] TextureNameHashes { get; set; } public ResourcePointerList64 Textures { get; set; } public Dictionary Dict { get; set; } public long MemoryUsage { get { long val = 0; if ((Textures != null) && (Textures.data_items != null)) { foreach (var tex in Textures.data_items) { if (tex != null) { val += tex.MemoryUsage; } } } return val; } } public TextureDictionary() { //this.TextureNameHashes = new ResourceSimpleList64(); this.Textures = new ResourcePointerList64(); } /// /// Reads the data-block from a stream. /// public override void Read(ResourceDataReader reader, params object[] parameters) { base.Read(reader, parameters); // read structure data this.Unknown_10h = reader.ReadUInt32(); this.Unknown_14h = reader.ReadUInt32(); this.Unknown_18h = reader.ReadUInt32(); this.Unknown_1Ch = reader.ReadUInt32(); this.TextureNameHashesPtr = reader.ReadStruct(); this.TextureNameHashes = reader.ReadUintsAt(this.TextureNameHashesPtr.EntriesPointer, this.TextureNameHashesPtr.EntriesCount); //this.TextureNameHashes = reader.ReadBlock>(); this.Textures = reader.ReadBlock>(); var dict = new Dictionary(); if ((Textures != null) && (Textures.data_items != null) && (TextureNameHashes != null)) { for (int i = 0; (i < Textures.data_items.Length) && (i < TextureNameHashes.Length); i++) { var tex = Textures.data_items[i]; var hash = TextureNameHashes[i]; dict[hash] = tex; } } Dict = dict;// new Dictionary(dict); } /// /// Writes the data-block to a stream. /// public override void Write(ResourceDataWriter writer, params object[] parameters) { base.Write(writer, parameters); // write structure data writer.Write(this.Unknown_10h); writer.Write(this.Unknown_14h); writer.Write(this.Unknown_18h); writer.Write(this.Unknown_1Ch); //writer.WriteBlock(this.TextureNameHashes); //TODO: fix! //writer.WriteBlock(this.Textures); } public override Tuple[] GetParts() { return new Tuple[] { //new Tuple(0x20, TextureNameHashes), //TODO: fix! new Tuple(0x30, Textures) }; } public Texture Lookup(uint hash) { Texture tex = null; if (Dict != null) { Dict.TryGetValue(hash, out tex); } return tex; } //public Dictionary GetDictionary() //{ // Dictionary td = new Dictionary(); // if ((Textures != null) && (Textures.data_items != null)) // { // var texs = Textures.data_items; // var hashes = TextureNameHashes; // for (int i = 0; (i < texs.Length) && (i < hashes.Length); i++) // { // td.Add(hashes[i], texs[i]); // } // } // return td; //} } [TypeConverter(typeof(ExpandableObjectConverter))] public class TextureBase : ResourceSystemBlock { public override long BlockLength { get { return 64; } } // structure data public uint VFT { get; set; } public uint Unknown_4h { get; set; } // 0x00000001 public uint Unknown_8h { get; set; } // 0x00000000 public uint Unknown_Ch { get; set; } // 0x00000000 public uint Unknown_10h { get; set; } // 0x00000000 public uint Unknown_14h { get; set; } // 0x00000000 public uint Unknown_18h { get; set; } // 0x00000000 public uint Unknown_1Ch { get; set; } // 0x00000000 public uint Unknown_20h { get; set; } // 0x00000000 public uint Unknown_24h { get; set; } // 0x00000000 public ulong NamePointer { get; set; } public uint Unknown_30h { get; set; } public uint Unknown_34h { get; set; } // 0x00000000 public uint Unknown_38h { get; set; } // 0x00000000 public uint Unknown_3Ch { get; set; } // 0x00000000 // reference data public string Name { get; set; } public uint NameHash { get; set; } /// /// Reads the data-block from a stream. /// public override void Read(ResourceDataReader reader, params object[] parameters) { // read structure data this.VFT = reader.ReadUInt32(); this.Unknown_4h = reader.ReadUInt32(); this.Unknown_8h = reader.ReadUInt32(); this.Unknown_Ch = reader.ReadUInt32(); this.Unknown_10h = reader.ReadUInt32(); this.Unknown_14h = reader.ReadUInt32(); this.Unknown_18h = reader.ReadUInt32(); this.Unknown_1Ch = reader.ReadUInt32(); this.Unknown_20h = reader.ReadUInt32(); this.Unknown_24h = reader.ReadUInt32(); this.NamePointer = reader.ReadUInt64(); this.Unknown_30h = reader.ReadUInt32(); this.Unknown_34h = reader.ReadUInt32(); this.Unknown_38h = reader.ReadUInt32(); this.Unknown_3Ch = reader.ReadUInt32(); // read reference data this.Name = reader.ReadStringAt( //BlockAt( this.NamePointer // offset ); if (!string.IsNullOrEmpty(Name)) { NameHash = JenkHash.GenHash(Name.ToLowerInvariant()); } } /// /// Writes the data-block to a stream. /// public override void Write(ResourceDataWriter writer, params object[] parameters) { // update structure data //this.NamePointer = (ulong)(this.Name != null ? this.Name.Position : 0); //TODO: fix // write structure data writer.Write(this.VFT); writer.Write(this.Unknown_4h); writer.Write(this.Unknown_8h); writer.Write(this.Unknown_Ch); writer.Write(this.Unknown_10h); writer.Write(this.Unknown_14h); writer.Write(this.Unknown_18h); writer.Write(this.Unknown_1Ch); writer.Write(this.Unknown_20h); writer.Write(this.Unknown_24h); writer.Write(this.NamePointer); writer.Write(this.Unknown_30h); writer.Write(this.Unknown_34h); writer.Write(this.Unknown_38h); writer.Write(this.Unknown_3Ch); } /// /// Returns a list of data blocks which are referenced by this block. /// public override IResourceBlock[] GetReferences() { var list = new List(); //if (Name != null) list.Add(Name); //TODO: fix return list.ToArray(); } public override string ToString() { return "TextureBase: " + Name; } } [TypeConverter(typeof(ExpandableObjectConverter))] public class Texture : TextureBase { public override long BlockLength { get { return 144; } } // structure data public uint Unknown_40h { get; set; } public uint Unknown_44h { get; set; } // 0x00000000 public uint Unknown_48h { get; set; } public uint Unknown_4Ch { get; set; } // 0x00000000 public ushort Width { get; set; } public ushort Height { get; set; } public ushort Unknown_54h { get; set; } // 0x0001 public ushort Stride { get; set; } public TextureFormat Format { get; set; } public byte Unknown_5Ch { get; set; } // 0x00 public byte Levels { get; set; } public ushort Unknown_5Eh { get; set; } // 0x0000 public uint Unknown_60h { get; set; } // 0x00000000 public uint Unknown_64h { get; set; } // 0x00000000 public uint Unknown_68h { get; set; } // 0x00000000 public uint Unknown_6Ch { get; set; } // 0x00000000 public ulong DataPointer { get; set; } public uint Unknown_78h { get; set; } // 0x00000000 public uint Unknown_7Ch { get; set; } // 0x00000000 public uint Unknown_80h { get; set; } // 0x00000000 public uint Unknown_84h { get; set; } // 0x00000000 public uint Unknown_88h { get; set; } // 0x00000000 public uint Unknown_8Ch { get; set; } // 0x00000000 // reference data public TextureData Data { get; set; } public long MemoryUsage { get { long val = 0; if (Data != null) { val += Data.FullData.LongLength; } return val; } } /// /// Reads the data-block from a stream. /// public override void Read(ResourceDataReader reader, params object[] parameters) { base.Read(reader, parameters); // read structure data this.Unknown_40h = reader.ReadUInt32(); this.Unknown_44h = reader.ReadUInt32(); this.Unknown_48h = reader.ReadUInt32(); this.Unknown_4Ch = reader.ReadUInt32(); this.Width = reader.ReadUInt16(); this.Height = reader.ReadUInt16(); this.Unknown_54h = reader.ReadUInt16(); this.Stride = reader.ReadUInt16(); this.Format = (TextureFormat)reader.ReadUInt32(); this.Unknown_5Ch = reader.ReadByte(); this.Levels = reader.ReadByte(); this.Unknown_5Eh = reader.ReadUInt16(); this.Unknown_60h = reader.ReadUInt32(); this.Unknown_64h = reader.ReadUInt32(); this.Unknown_68h = reader.ReadUInt32(); this.Unknown_6Ch = reader.ReadUInt32(); this.DataPointer = reader.ReadUInt64(); this.Unknown_78h = reader.ReadUInt32(); this.Unknown_7Ch = reader.ReadUInt32(); this.Unknown_80h = reader.ReadUInt32(); this.Unknown_84h = reader.ReadUInt32(); this.Unknown_88h = reader.ReadUInt32(); this.Unknown_8Ch = reader.ReadUInt32(); // read reference data this.Data = reader.ReadBlockAt( this.DataPointer, // offset this.Format, this.Width, this.Height, this.Levels, this.Stride ); } /// /// Writes the data-block to a stream. /// public override void Write(ResourceDataWriter writer, params object[] parameters) { base.Write(writer, parameters); this.DataPointer = (ulong)this.Data.FilePosition; // write structure data writer.Write(this.Unknown_40h); writer.Write(this.Unknown_44h); writer.Write(this.Unknown_48h); writer.Write(this.Unknown_4Ch); writer.Write(this.Width); writer.Write(this.Height); writer.Write(this.Unknown_54h); writer.Write(this.Stride); writer.Write((uint)this.Format); writer.Write(this.Unknown_5Ch); writer.Write(this.Levels); writer.Write(this.Unknown_5Eh); writer.Write(this.Unknown_60h); writer.Write(this.Unknown_64h); writer.Write(this.Unknown_68h); writer.Write(this.Unknown_6Ch); writer.Write(this.DataPointer); writer.Write(this.Unknown_78h); writer.Write(this.Unknown_7Ch); writer.Write(this.Unknown_80h); writer.Write(this.Unknown_84h); writer.Write(this.Unknown_88h); writer.Write(this.Unknown_8Ch); } /// /// Returns a list of data blocks which are referenced by this block. /// public override IResourceBlock[] GetReferences() { var list = new List(base.GetReferences()); list.Add(Data); return list.ToArray(); } public override string ToString() { return "Texture: " + Width.ToString() + "x" + Height.ToString() + ": " + Name; } } [TypeConverter(typeof(ExpandableObjectConverter))] public class TextureData : ResourceGraphicsBlock { public override long BlockLength { get { return FullData.Length; } } public byte[] FullData { get; set; } /// /// Reads the data-block from a stream. /// public override void Read(ResourceDataReader reader, params object[] parameters) { uint format = Convert.ToUInt32(parameters[0]); int Width = Convert.ToInt32(parameters[1]); int Height = Convert.ToInt32(parameters[2]); int Levels = Convert.ToInt32(parameters[3]); int Stride = Convert.ToInt32(parameters[4]); int fullLength = 0; int length = Stride * Height; for (int i = 0; i < Levels; i++) { fullLength += length; length /= 4; } FullData = reader.ReadBytes(fullLength); } /// /// Writes the data-block to a stream. /// public override void Write(ResourceDataWriter writer, params object[] parameters) { writer.Write(FullData); } } public enum TextureFormat : uint { D3DFMT_A8R8G8B8 = 21, D3DFMT_A1R5G5B5 = 25, D3DFMT_A8 = 28, D3DFMT_A8B8G8R8 = 32, D3DFMT_L8 = 50, // fourCC D3DFMT_DXT1 = 0x31545844, D3DFMT_DXT3 = 0x33545844, D3DFMT_DXT5 = 0x35545844, D3DFMT_ATI1 = 0x31495441, D3DFMT_ATI2 = 0x32495441, D3DFMT_BC7 = 0x20374342, //UNKNOWN } }