Ejemplo n.º 1
0
 public FourthGenZoneSet(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea)
 {
     _metaArea = metaArea;
     Load(values, reader);
 }
 public ThirdGenSoundResourceGestalt(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo)
 {
     Load(values, reader, metaArea, buildInfo);
 }
Ejemplo n.º 3
0
        /// <summary>
        ///     Serializes the header's values, storing them into a StructureValueCollection.
        /// </summary>
        /// <param name="localeArea">The locale area of the cache file. Can be null.</param>
        /// <param name="localePointerMask">The value to add to locale pointers to translate them to file offsets.</param>
        /// <returns>The resulting StructureValueCollection.</returns>
        public StructureValueCollection Serialize(FileSegmentGroup localeArea)
        {
            var values = new StructureValueCollection();

            values.SetInteger("file size", FileSize);
            values.SetInteger("type", (uint)Type);
            values.SetString("internal name", InternalName);
            values.SetString("scenario path", ScenarioPath);
            //values.SetInteger("xdk version", (uint) XDKVersion);

            //AdjustPartitions();
            //values.SetArray("partitions", SerializePartitions());

            //RebuildInteropData(localeArea);

            /*
             *          values.SetArray("offset masks", SectionOffsetMasks.Select(m =>
             *          {
             *                  var result = new StructureValueCollection();
             *                  result.SetInteger("mask", m);
             *                  return result;
             *          }).ToArray());
             *
             *          values.SetArray("sections", Sections.Select(s => s.Serialize()).ToArray());
             *          values.SetInteger("tag buffer offset", Sections[(int) FourthGenInteropSectionType.Tag].VirtualAddress);
             */
            /*
             *          if (MetaArea != null)
             *          {
             *                  values.SetInteger("virtual base address", MetaArea.BasePointer);
             *                  values.SetInteger("index header address", IndexHeaderLocation.AsPointer());
             *                  values.SetInteger("virtual size", (uint) MetaArea.Size);
             *          }
             */

            if (StringBlockLocation != null)
            {
                values.SetInteger("string block offset", StringBlockLocation.AsPointer());
            }

            values.SetInteger("string table count", (uint)StringIDCount);
            if (StringIDData != null)
            {
                values.SetInteger("string table size", (uint)StringIDData.Size);
                values.SetInteger("string table offset", StringIDDataLocation.AsPointer());
            }

            if (StringIDIndexTableLocation != null)
            {
                values.SetInteger("string index table offset", StringIDIndexTableLocation.AsPointer());
            }

            if (StringArea != null)
            {
                values.SetInteger("string data size", (uint)StringArea.Size);
            }

            /*
             *          values.SetInteger("file table count", (uint) FileNameCount);
             *          if (FileNameData != null)
             *          {
             *                  values.SetInteger("file table offset", FileNameDataLocation.AsPointer());
             *                  values.SetInteger("file table size", (uint) FileNameData.Size);
             *          }
             *
             *          if (FileNameIndexTableLocation != null)
             *                  values.SetInteger("file index table offset", FileNameIndexTableLocation.AsPointer());
             */

            if (localeArea != null)
            {
                values.SetInteger("locale data index offset", localeArea.BasePointer);
                values.SetInteger("locale data size", (uint)localeArea.Size);
            }

            /*
             *          if (UnknownTableLocation != null)
             *          {
             *                  values.SetInteger("unknown table count", (uint) UnknownCount);
             *                  values.SetInteger("unknown table offset", UnknownTableLocation.AsPointer());
             *          }
             * */

            return(values);
        }
Ejemplo n.º 4
0
 internal Script(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs,
                 EngineDescription buildInfo, IPointerExpander expander)
 {
     Load(values, reader, metaArea, stringIDs, buildInfo, expander);
 }
Ejemplo n.º 5
0
 public ThirdGenModelRegion(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea,
                            EngineDescription buildInfo)
 {
     Load(values, reader, metaArea, buildInfo);
 }
        public SecondGenScenarioScriptFile(ITag scenarioTag, ITag scriptTag, string tagName, FileSegmentGroup metaArea,
                                           StringIDSource stringIDs, EngineDescription buildInfo, IPointerExpander expander)
        {
            _scenarioTag = scenarioTag;
            _expander    = expander;
            _scriptTag   = scriptTag;
            _stringIDs   = stringIDs;
            _metaArea    = metaArea;
            _buildInfo   = buildInfo;
            Name         = tagName.Substring(tagName.LastIndexOf('\\') + 1) + ".hsc";

            DefineScriptObjectTagBlocks();
        }
Ejemplo n.º 7
0
 public FourthGenResourceMetaLoader(EngineDescription buildInfo, FileSegmentGroup metaArea)
 {
     _buildInfo = buildInfo;
     _metaArea  = metaArea;
 }
Ejemplo n.º 8
0
 /// <summary>
 ///     Writes data to a reflexive, reallocating the original.
 /// </summary>
 /// <param name="entries">The entries to write.</param>
 /// <param name="oldCount">The old count.</param>
 /// <param name="oldAddress">The old address.</param>
 /// <param name="layout">The layout of the data to write.</param>
 /// <param name="metaArea">The meta area of the cache file.</param>
 /// <param name="allocator">The cache file's meta allocator.</param>
 /// <param name="stream">The stream to manipulate.</param>
 /// <returns>The address of the new reflexive, or 0 if the entry list is empty and the reflexive was freed.</returns>
 public static long WriteReflexive(ICollection <StructureValueCollection> entries, int oldCount, long oldAddress,
                                   StructureLayout layout, FileSegmentGroup metaArea, MetaAllocator allocator, IStream stream)
 {
     return(WriteReflexive(entries, oldCount, oldAddress, entries.Count, layout, metaArea, allocator, stream));
 }
        private void LoadPlaybackParameters(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo)
        {
            var count   = (int)values.GetInteger("number of playback parameters");
            var address = (uint)values.GetInteger("playback parameters table address");
            var layout  = buildInfo.Layouts.GetLayout("sound playback parameters");
            var entries = TagBlockReader.ReadTagBlock(reader, count, address, layout, metaArea);

            SoundPlaybackParameters = (from entry in entries
                                       select new ThirdGenSoundPlaybackParameter(entry)).ToArray <ISoundPlaybackParameter>();
        }
Ejemplo n.º 10
0
        private void Load(StructureValueCollection values, FileSegmenter segmenter)
        {
            _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size"));

            var metaOffset = (int)values.GetInteger("meta offset");

            int tagTableSize = (int)values.GetInteger("tag data offset");
            int tagDataSize  = (int)values.GetInteger("tag data size");

            var headSegment = new FileSegment(
                segmenter.DefineSegment(metaOffset, tagTableSize, 0x1000, SegmentResizeOrigin.Beginning), segmenter);

            var metaSize       = (int)values.GetInteger("meta size");
            int metaOffsetMask = (int)values.GetInteger("meta offset mask");

            var metaSegment = new FileSegment(
                segmenter.DefineSegment(metaOffset + tagTableSize, tagDataSize, 0x1000, SegmentResizeOrigin.End), segmenter);

            MetaArea = new FileSegmentGroup(new MetaOffsetConverter(headSegment, (uint)metaOffsetMask));

            IndexHeaderLocation = MetaArea.AddSegment(headSegment);
            MetaArea.AddSegment(metaSegment);

            Type = (CacheFileType)values.GetInteger("type");

            var headerGroup = new FileSegmentGroup();

            headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None));

            StringIDCount = (int)values.GetInteger("string table count");
            var sidDataSize = (int)values.GetInteger("string table size");

            StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1,
                                                 SegmentResizeOrigin.End);
            StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4,
                                                       SegmentResizeOrigin.End);

            FileNameCount = (int)values.GetInteger("file table count");
            var fileDataSize = (int)values.GetInteger("file table size");

            FileNameData = segmenter.WrapSegment((int)values.GetInteger("file table offset"), fileDataSize, 1,
                                                 SegmentResizeOrigin.End);
            FileNameIndexTable = segmenter.WrapSegment((int)values.GetInteger("file index table offset"), FileNameCount * 4, 4,
                                                       SegmentResizeOrigin.End);

            InternalName = values.GetString("internal name");
            ScenarioName = values.GetString("scenario name");

            StringArea = new FileSegmentGroup();
            StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80,
                                                        SegmentResizeOrigin.End));
            StringArea.AddSegment(StringIDIndexTable);
            StringArea.AddSegment(StringIDData);
            StringArea.AddSegment(FileNameIndexTable);
            StringArea.AddSegment(FileNameData);

            StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea);
            StringIDDataLocation       = SegmentPointer.FromOffset(StringIDData.Offset, StringArea);
            FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea);
            FileNameDataLocation       = SegmentPointer.FromOffset(FileNameData.Offset, StringArea);

            LocaleArea = new FileSegmentGroup();

            var rawTableOffset = (int)values.GetInteger("raw table offset");
            var rawTableSize   = (int)values.GetInteger("raw table size");

            // It is apparently possible to create a cache without a raw table, but -1 gets written as the offset
            if (rawTableOffset != -1)
            {
                RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 0x80, SegmentResizeOrigin.End);
            }

            Checksum = (uint)values.GetInteger("checksum");

            // Set up a bogus partition table
            Partitions    = new Partition[1];
            Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size);
        }
Ejemplo n.º 11
0
        /// <summary>
        ///     Rebuilds the interop data table in a cache file.
        /// </summary>
        /// <param name="localeArea">The localization area of the file.</param>
        private void RebuildInteropData(FileSegmentGroup localeArea)
        {
            ThirdGenInteropSection debugSection  = Sections[(int)ThirdGenInteropSectionType.Debug];
            ThirdGenInteropSection rsrcSection   = Sections[(int)ThirdGenInteropSectionType.Resource];
            ThirdGenInteropSection tagSection    = Sections[(int)ThirdGenInteropSectionType.Tag];
            ThirdGenInteropSection localeSection = Sections[(int)ThirdGenInteropSectionType.Localization];

            // Recompute base addresses
            // Section addresses are usually in the following order: resource, locale, tag, debug.
            // Each address can immediately follow after the previous non-null section,
            // even though this isn't the case in some of the official files (because of removed debug data).
            //
            // TODO: This could possibly be made into a for loop and cleaned up if the pointer converters are stored in an array.
            // I just want to get this working for now.
            //rsrcSection.VirtualAddress = 0; // This is (not) always zero
            rsrcSection.Size             = (ResourcePointerConverter != null) ? (uint)RawTable.Size : 0;
            localeSection.VirtualAddress = (LocalePointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size : 0;
            localeSection.Size           = (LocalePointerConverter != null) ? (uint)localeArea.Size : 0;
            tagSection.VirtualAddress    = (TagBufferPointerConverter != null)
                                ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size
                                : 0;
            tagSection.Size             = (TagBufferPointerConverter != null) ? (uint)MetaArea.Size : 0;
            debugSection.VirtualAddress = (DebugPointerConverter != null)
                                ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size + tagSection.Size
                                : 0;
            debugSection.Size = (DebugPointerConverter != null) ? (uint)StringArea.Size : 0;

            // If the offset mask for the debug section wasn't originally zero, then we have to subtract the first partition size from the debug base address
            // Not entirely sure why this is the case, but that's what the official files do
            if (debugSection.VirtualAddress != 0 && SectionOffsetMasks[(int)ThirdGenInteropSectionType.Debug] != 0)
            {
                debugSection.VirtualAddress -= Partitions[0].Size;
            }

            // Recompute offset masks
            SectionOffsetMasks[(int)ThirdGenInteropSectionType.Debug] = (debugSection.Size > 0)
                                ? (uint)(StringArea.Offset - debugSection.VirtualAddress)
                                : 0;
            SectionOffsetMasks[(int)ThirdGenInteropSectionType.Resource] = (rsrcSection.Size > 0)
                                ? (uint)(RawTable.Offset - rsrcSection.VirtualAddress)
                                : 0;
            SectionOffsetMasks[(int)ThirdGenInteropSectionType.Tag] = (tagSection.Size > 0)
                                ? (uint)(MetaArea.Offset - tagSection.VirtualAddress)
                                : 0;
            SectionOffsetMasks[(int)ThirdGenInteropSectionType.Localization] = (localeSection.Size > 0)
                                ? (uint)(localeArea.Offset - localeSection.VirtualAddress)
                                : 0;

            // Update pointer converters
            if (DebugPointerConverter != null)
            {
                DebugPointerConverter.BasePointer = debugSection.VirtualAddress;
            }
            if (ResourcePointerConverter != null)
            {
                ResourcePointerConverter.BasePointer = rsrcSection.VirtualAddress;
            }
            if (TagBufferPointerConverter != null)
            {
                TagBufferPointerConverter.BasePointer = tagSection.VirtualAddress;
            }
            if (LocalePointerConverter != null)
            {
                LocalePointerConverter.BasePointer = localeSection.VirtualAddress;
            }
        }
        public FourthGenSimulationDefinitionTable(ITag scenario, TagTable tags, IReader reader, FileSegmentGroup metaArea, MetaAllocator allocator, EngineDescription buildInfo)
        {
            _scenario  = scenario;
            _tags      = tags;
            _metaArea  = metaArea;
            _allocator = allocator;
            _buildInfo = buildInfo;

            Load(reader);
        }
Ejemplo n.º 13
0
 public ThirdGenLanguageGlobals(StructureValueCollection values, FileSegmenter segmenter,
                                IPointerConverter localePointerConverter, EngineDescription buildInfo)
 {
     LocaleArea = new FileSegmentGroup(localePointerConverter);
     Languages  = LoadLanguages(values, segmenter, buildInfo);
 }
Ejemplo n.º 14
0
		public ThirdGenTag(StructureValueCollection values, ushort index, FileSegmentGroup metaArea,
			IList<ITagGroup> groupList, IPointerExpander expander)
		{
			Load(values, index, metaArea, groupList, expander);
		}
Ejemplo n.º 15
0
        private void Load(StructureValueCollection values, ushort index, FileSegmentGroup header, FileSegmentGroup metaArea, IList <ITagClass> classList)
        {
            uint address = values.GetInteger("memory address");

            if (address != 0 && address != 0xFFFFFFFF)
            {
                MetaLocation   = SegmentPointer.FromPointer(address, metaArea);
                HeaderLocation = SegmentPointer.FromPointer(address, header);
            }

            var classIndex = (int)values.GetInteger("class index");

            if (classIndex >= 0 && classIndex < classList.Count)
            {
                Class = classList[classIndex];
            }

            var salt = (ushort)values.GetInteger("datum index salt");

            if (salt != 0xFFFF)
            {
                Index = new DatumIndex(salt, index);
            }
            else
            {
                Index = DatumIndex.Null;
            }
        }
Ejemplo n.º 16
0
 public SecondGenLanguageGlobals(StructureValueCollection values, FileSegmenter segmenter, EngineDescription buildInfo)
 {
     LocaleArea = new FileSegmentGroup();
     Languages  = LoadLanguages(values, segmenter, buildInfo);
 }
Ejemplo n.º 17
0
 public FirstGenTagTable(IReader reader, StructureValueCollection headerValues, FileSegmentGroup metaArea,
                         EngineDescription buildInfo)
 {
     Load(reader, headerValues, metaArea, buildInfo);
 }
Ejemplo n.º 18
0
 public FourthGenSound(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea,
                       EngineDescription buildInfo)
 {
     Load(values, reader, metaArea, buildInfo);
 }
Ejemplo n.º 19
0
        public static StructureValueCollection[] ReadTagBlock(IReader reader, int count, long address,
                                                              StructureLayout elementLayout, FileSegmentGroup metaArea)
        {
            if (elementLayout.Size == 0)
            {
                throw new ArgumentException("The element layout must have a size associated with it.");
            }

            // Handle null pointers
            if (count <= 0 || !metaArea.ContainsPointer(address))
            {
                return(new StructureValueCollection[0]);
            }

            // Convert the address to an offset and seek to it
            int offset = metaArea.PointerToOffset(address);

            reader.SeekTo(offset);

            // Read the entries
            var result = new StructureValueCollection[count];

            for (int i = 0; i < count; i++)
            {
                result[i] = StructureReader.ReadStructure(reader, elementLayout);
            }

            return(result);
        }
Ejemplo n.º 20
0
 public RawData(string name, uint offset, string format, long address, string value, int length, uint pluginLine, string tooltip, FileSegmentGroup metaArea)
     : base(name, offset, address, pluginLine, tooltip)
 {
     _value    = value;
     _length   = length;
     _format   = format;
     _metaArea = metaArea;
 }
Ejemplo n.º 21
0
        private void LoadVertexGroups(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea,
                                      EngineDescription buildInfo, IModelSubmesh[] submeshes)
        {
            var             count   = (int)values.GetInteger("number of vertex groups");
            uint            address = values.GetInteger("vertex group table address");
            StructureLayout layout  = buildInfo.Layouts.GetLayout("model vertex group");

            StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, metaArea);

            VertexGroups = (from entry in entries
                            select new ThirdGenModelVertexGroup(entry, submeshes)).ToArray();
        }
Ejemplo n.º 22
0
        private void Load(StructureValueCollection values, FileSegmenter segmenter)
        {
            _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size"));

            var metaOffset = (int)values.GetInteger("meta offset");

            int metaSize;

            if (values.HasInteger("tag data offset"))
            {
                metaSize = (int)values.GetInteger("tag data offset") + (int)values.GetInteger("tag data size");
            }
            else
            {
                metaSize = (int)values.GetInteger("meta size");
            }

            // store the stock meta size since xbox's size is virtual
            //todo: figure out how this is calculated instead of doing a hack
            _saved_meta_size_hack = (uint)values.GetInteger("meta size");

            var metaSegment = new FileSegment(
                segmenter.DefineSegment(metaOffset, metaSize, 0x4, SegmentResizeOrigin.Beginning), segmenter);

            uint metaOffsetMask;

            if (values.HasInteger("xbox meta offset mask"))
            {
                metaOffsetMask = (uint)values.GetInteger("xbox meta offset mask");
            }
            else
            {
                metaOffsetMask = (uint)(values.GetInteger("tag table offset") - values.GetInteger("meta header size"));
            }

            MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask));

            IndexHeaderLocation = MetaArea.AddSegment(metaSegment);

            Type = (CacheFileType)values.GetInteger("type");
            var headerGroup = new FileSegmentGroup();

            headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None));

            //h2 alpha forcing this to be shoved in
            if (values.HasInteger("string table count"))
            {
                StringIDCount = (int)values.GetInteger("string table count");
                var sidDataSize = (int)values.GetInteger("string table size");
                StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1,
                                                     SegmentResizeOrigin.End);
                StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4,
                                                           SegmentResizeOrigin.End);

                StringArea = new FileSegmentGroup();
                if (values.HasInteger("string block offset"))
                {
                    StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80,
                                                                SegmentResizeOrigin.End));
                }
                StringArea.AddSegment(StringIDIndexTable);
                StringArea.AddSegment(StringIDData);

                StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea);
                StringIDDataLocation       = SegmentPointer.FromOffset(StringIDData.Offset, StringArea);
            }
            else
            {
                //dummy
                StringIDCount      = 0;
                StringIDData       = _eofSegment;
                StringIDIndexTable = _eofSegment;
            }

            InternalName = values.GetString("internal name");

            Checksum = (uint)values.GetInteger("checksum");

            // dummy partition
            Partitions    = new Partition[1];
            Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size);
        }
Ejemplo n.º 23
0
 public ThirdGenZoneSet(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, IPointerExpander expander)
 {
     _metaArea = metaArea;
     Load(values, reader, expander);
 }
Ejemplo n.º 24
0
        private void LoadBoundingBoxes(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea,
                                       EngineDescription buildInfo)
        {
            var             count   = (int)values.GetInteger("number of bounding boxes");
            uint            address = (uint)values.GetInteger("bounding box table address");
            StructureLayout layout  = buildInfo.Layouts.GetLayout("model bounding box");

            StructureValueCollection[] entries = TagBlockReader.ReadTagBlock(reader, 1, address, layout, metaArea);

            BoundingBoxes = (from entry in entries
                             select BoundingBox.Deserialize(entry)).ToArray();
        }
Ejemplo n.º 25
0
        private void LoadPermutations(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea,
                                      EngineDescription buildInfo)
        {
            var             count   = (int)values.GetInteger("number of permutations");
            uint            address = values.GetInteger("permutation table address");
            StructureLayout layout  = buildInfo.Layouts.GetLayout("model permutation");

            StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, metaArea);

            Permutations = (from entry in entries
                            select new ThirdGenModelPermutation(entry)).ToArray();
        }
Ejemplo n.º 26
0
 public SecondGenTag(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagGroup> groupsById)
 {
     Load(values, metaArea, groupsById);
 }
        private void LoadSoundPlaybacks(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo)
        {
            var count   = (int)values.GetInteger("number of playbacks");
            var address = values.GetInteger("playback table address");
            var layout  = buildInfo.Layouts.GetLayout("sound playbacks");
            var entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, metaArea);

            SoundPlaybacks = (from entry in entries
                              select new ThirdGenSoundPlayback(entry, SoundNames)).ToArray <ISoundPlayback>();
        }
Ejemplo n.º 28
0
        /*
         * public FourthGenTag(StructureValueCollection values, ushort index, FileSegmentGroup metaArea,
         *              IList<ITagClass> classList)
         *      {
         *              Load(values, index, metaArea, classList);
         *      }
         */

        public FourthGenTag(StructureValueCollection values, ushort index, FileSegmentGroup header, FileSegmentGroup metaArea, IList <ITagClass> classList)
        {
            Load(values, index, header, metaArea, classList);
        }
Ejemplo n.º 29
0
        /*
         * private void LoadInteropData(StructureValueCollection map_values, StructureValueCollection tag_values)
         *      {
         *              // TODO: fix this shit for the h3beta
         *              //SectionOffsetMasks = headerValues.GetArray("offset masks").Select(v => v.GetInteger("mask")).ToArray();
         *              //Sections = headerValues.GetArray("sections").Select(v => new FourthGenInteropSection(v)).ToArray();
         *
         *              //DebugPointerConverter = MakePointerConverter(FourthGenInteropSectionType.Debug);
         *              //ResourcePointerConverter = MakePointerConverter(FourthGenInteropSectionType.Resource);
         *              //TagBufferPointerConverter = MakePointerConverter(FourthGenInteropSectionType.Tag);
         *              //LocalePointerConverter = MakePointerConverter(FourthGenInteropSectionType.Localization);
         *      }
         */
        /*
         *      private BasedPointerConverter MakePointerConverter(uint tags_data_size)
         *      {
         *
         *              if (Sections[(int) section].Size == 0)
         *                      return null;
         *
         *              uint baseAddress = Sections[(int) section].VirtualAddress;
         *              uint mask = SectionOffsetMasks[(int) section];
         *              return new BasedPointerConverter(baseAddress, (int) (baseAddress + mask));
         *
         *  return new BasedPointerConverter(0, 0);
         *      }
         */

        /*
         *      private FileSegment CalculateRawTableSegment(FileSegmenter segmenter)
         *      {
         *              if (ResourcePointerConverter != null)
         *              {
         *                      int rawTableOffset = ResourcePointerConverter.PointerToOffset(ResourcePointerConverter.BasePointer);
         *                      var rawTableSize = (int) Sections[(int) FourthGenInteropSectionType.Resource].Size;
         *                      return segmenter.WrapSegment(rawTableOffset, rawTableSize, 0x1000, SegmentResizeOrigin.End);
         *              }
         *              return null;
         *      }
         */
        /*
         * // TODO: Replace this function with the ability to parse the tags.dat file for this information.
         *      private FileSegment CalculateTagDataSegment(StructureValueCollection values, FileSegmenter segmenter)
         *      {
         *  int tagDataOffset = (int)values.GetInteger("tag buffer offset");
         *
         *
         *
         *              if (TagBufferPointerConverter != null)
         *              {
         *                      int tagDataOffset = TagBufferPointerConverter.PointerToOffset(TagBufferPointerConverter.BasePointer);
         *                      var tagDataSize = (int) values.GetInteger("virtual size");
         *                      return segmenter.WrapSegment(tagDataOffset, tagDataSize, 0x10000, SegmentResizeOrigin.Beginning);
         *              }
         *              return null;
         *      }
         */

        private void CalculateStringGroup(StructureValueCollection values, FileSegmenter segmenter)
        {
            if (DebugPointerConverter == null)
            {
                return;
            }

            StringArea = new FileSegmentGroup(DebugPointerConverter);

            // StringIDs
            StringIDCount = (int)values.GetInteger("string table count");
            if (StringIDCount > 0)
            {
                int sidIndexTableOff = DebugPointerConverter.PointerToOffset(values.GetInteger("string index table offset"));
                int sidDataOff       = DebugPointerConverter.PointerToOffset(values.GetInteger("string table offset"));

                var sidTableSize = (int)values.GetInteger("string table size");
                StringIDIndexTable = segmenter.WrapSegment(sidIndexTableOff, StringIDCount * 4, 4, SegmentResizeOrigin.End);
                StringIDData       = segmenter.WrapSegment(sidDataOff, sidTableSize, 1, SegmentResizeOrigin.End);

                StringIDIndexTableLocation = StringArea.AddSegment(StringIDIndexTable);
                StringIDDataLocation       = StringArea.AddSegment(StringIDData);

                // idk what this is, but H3Beta has it
                if (values.HasInteger("string block offset"))
                {
                    int sidBlockOff = DebugPointerConverter.PointerToOffset(values.GetInteger("string block offset"));
                    StringBlock         = segmenter.WrapSegment(sidBlockOff, StringIDCount * 0x80, 0x80, SegmentResizeOrigin.End);
                    StringBlockLocation = StringArea.AddSegment(StringBlock);
                }
            }

            /*
             *          // Tag names
             *          FileNameCount = (int) values.GetInteger("file table count");
             *          if (FileNameCount > 0)
             *          {
             *                  int nameIndexTableOff = DebugPointerConverter.PointerToOffset(values.GetInteger("file index table offset"));
             *                  int nameDataOff = DebugPointerConverter.PointerToOffset(values.GetInteger("file table offset"));
             *
             *                  var fileTableSize = (int) values.GetInteger("file table size");
             *                  FileNameIndexTable = segmenter.WrapSegment(nameIndexTableOff, FileNameCount*4, 4, SegmentResizeOrigin.End);
             *                  FileNameData = segmenter.WrapSegment(nameDataOff, fileTableSize, 1, SegmentResizeOrigin.End);
             *
             *                  FileNameIndexTableLocation = StringArea.AddSegment(FileNameIndexTable);
             *                  FileNameDataLocation = StringArea.AddSegment(FileNameData);
             *          }
             */
            /*
             * // Some H4-only unknown table
             * if (values.HasInteger("unknown table count") && values.HasInteger("unknown table offset"))
             * {
             *  UnknownCount = (int) values.GetInteger("unknown table count");
             *  if (UnknownCount > 0)
             *  {
             *      int unknownOff = DebugPointerConverter.PointerToOffset(values.GetInteger("unknown table offset"));
             *      UnknownTable = segmenter.WrapSegment(unknownOff, UnknownCount*0x10, 0x10, SegmentResizeOrigin.End);
             *      UnknownTableLocation = StringArea.AddSegment(UnknownTable);
             *  }
             * }
             */
        }
        public ThirdGenSimulationDefinitionTable(ITag scenario, TagTable tags, IReader reader, FileSegmentGroup metaArea, MetaAllocator allocator, EngineDescription buildInfo, IPointerExpander expander)
        {
            _scenario  = scenario;
            _tags      = tags;
            _metaArea  = metaArea;
            _allocator = allocator;
            _buildInfo = buildInfo;
            _expander  = expander;

            Load(reader);
        }