예제 #1
0
        /// <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));
                }
            }
        }