/// <summary> /// Reads the tags.dat file. /// </summary> /// <param name="reader">The stream to read from.</param> private void Load(BinaryReader reader) { // Read file header reader.BaseStream.Position = 0x4; var tagListOffset = reader.ReadInt32(); // 0x4 uint32 offset table offset var tagCount = reader.ReadInt32(); // 0x8 uint32 number of tags // Read tag offset list reader.BaseStream.Position = tagListOffset; for (var i = 0; i < tagCount; i++) { _headerOffsets.Add(reader.ReadUInt32()); } // Read each tag for (var i = 0; i < tagCount; i++) { if (_headerOffsets[i] == 0) { // Offset of 0 = null tag _tags.Add(null); continue; } // Read header reader.BaseStream.Position = _headerOffsets[i]; var checksum = reader.ReadUInt32(); // 0x00 uint32 checksum? var totalSize = reader.ReadUInt32(); // 0x04 uint32 total size var numDependencies = reader.ReadInt16(); // 0x08 int16 dependencies count var numDataFixups = reader.ReadInt16(); // 0x0A int16 data fixup count var numResourceFixups = reader.ReadInt16(); // 0x0C int16 resource fixup count reader.BaseStream.Position += 2; // 0x0E int16 (padding) var mainStructOffset = reader.ReadUInt32(); // 0x10 uint32 main struct offset var tagClass = new MagicNumber(reader.ReadInt32()); // 0x14 int32 class var parentClass = new MagicNumber(reader.ReadInt32()); // 0x18 int32 parent class var grandparentClass = new MagicNumber(reader.ReadInt32()); // 0x1C int32 grandparent class var classId = reader.ReadUInt32(); // 0x20 uint32 class stringid var totalHeaderSize = CalculateHeaderSize(numDependencies, numDataFixups, numResourceFixups); // Construct the tag object var tag = new HaloTag { Index = i, Class = tagClass, ParentClass = parentClass, GrandparentClass = grandparentClass, MainStructOffset = mainStructOffset - totalHeaderSize, Offset = _headerOffsets[i] + totalHeaderSize, Size = totalSize - totalHeaderSize, Checksum = checksum, ClassId = classId }; _tags.Add(tag); // Read dependencies for (var j = 0; j < numDependencies; j++) { tag.Dependencies.Add(reader.ReadInt32()); } // Read fixup pointers var dataFixupPointers = new uint[numDataFixups]; for (var j = 0; j < numDataFixups; j++) { dataFixupPointers[j] = reader.ReadUInt32(); } var resourceFixupPointers = new uint[numResourceFixups]; for (var j = 0; j < numResourceFixups; j++) { resourceFixupPointers[j] = reader.ReadUInt32(); } // Process fixups foreach (var fixup in dataFixupPointers) { tag.DataFixups.Add(ReadFixup(reader, fixup, _headerOffsets[i], totalHeaderSize)); } foreach (var fixup in resourceFixupPointers) { tag.ResourceFixups.Add(ReadFixup(reader, fixup, _headerOffsets[i], totalHeaderSize)); } } }