Ejemplo n.º 1
0
        private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList <ITagClass> classList, IPointerExpander expander)
        {
            uint address = (uint)values.GetInteger("memory address");

            if (address != 0 && address != 0xFFFFFFFF)
            {
                long expanded = expander.Expand(address);

                MetaLocation = SegmentPointer.FromPointer(expanded, metaArea);
            }

            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.º 2
0
        private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream)
        {
            // Don't write anything if the block has already been written
            if (_dataBlockAddresses.ContainsKey(block))
            {
                return;
            }

            // Associate the location with the block
            _dataBlockAddresses[block] = location.AsPointer();

            // Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
            using (var buffer = new MemoryStream(block.Data.Length))
            {
                var bufferWriter = new EndianWriter(buffer, stream.Endianness);
                bufferWriter.WriteBlock(block.Data);

                // Apply fixups
                FixBlockReferences(block, bufferWriter, stream);
                FixTagReferences(block, bufferWriter, stream);
                FixResourceReferences(block, bufferWriter, stream);
                FixStringIDReferences(block, bufferWriter);

                // Write the buffer to the file
                stream.SeekTo(location.AsOffset());
                stream.WriteBlock(buffer.GetBuffer(), 0, (int)buffer.Length);
            }

            // Write shader fixups (they can't be done in-memory because they require cache file expansion)
            FixShaderReferences(block, stream, (int)location.AsOffset());
        }
Ejemplo n.º 3
0
        private void AdjustPartitions()
        {
            if (MetaArea == null)
            {
                return;
            }

            // Find the first partition and change it to the meta area's base address
            Partition partition = Partitions.First();

            if (partition != null)
            {
                partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea);
            }

            // Recalculate the size of each partition
            int partitionEnd = MetaArea.Offset + MetaArea.Size;

            for (int i = Partitions.Length - 1; i >= 0; i--)
            {
                if (Partitions[i].BasePointer == null)
                {
                    continue;
                }

                int offset = Partitions[i].BasePointer.AsOffset();
                Partitions[i].Size = (uint)(partitionEnd - offset);
                partitionEnd       = offset;
            }
        }
        private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList <ITagClass> classList)
        {
            uint address = values.GetInteger("memory address");

            VirtualAddr = address;
            address     = NewPointerConverter.ConvertToPointer(address);
            if (address != 0 && address != 0xFFFFFFFF)
            {
                MetaLocation = SegmentPointer.FromPointer(address, metaArea);
            }

            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.º 5
0
        private void Load(StructureValueCollection values, FileSegmenter segmenter)
        {
            segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning);             // Define a segment for the header
            _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size"));

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

            LoadInteropData(values);
            RawTable = CalculateRawTableSegment(segmenter);

            InternalName = values.GetString("internal name");
            ScenarioName = values.GetString("scenario name");
            XDKVersion   = (int)values.GetInteger("xdk version");

            FileSegment metaSegment = CalculateTagDataSegment(values, segmenter);

            if (metaSegment != null)
            {
                ulong virtualBase = values.GetInteger("virtual base address");
                MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, (long)virtualBase));
                MetaArea.AddSegment(metaSegment);

                IndexHeaderLocation = SegmentPointer.FromPointer((long)values.GetInteger("index header address"), MetaArea);
                Partitions          = LoadPartitions(values.GetArray("partitions"));
            }
            else
            {
                Partitions = new Partition[0];
            }

            CalculateStringGroup(values, segmenter);

            Checksum = (uint)values.GetInteger("checksum");
        }
Ejemplo n.º 6
0
 public FourthGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer headerLocation, SegmentPointer metaLocation)
 {
     Index          = index;
     Class          = tagClass;
     MetaLocation   = metaLocation;
     HeaderLocation = headerLocation;
 }
 public NewThirdGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer metaLocation, uint virtualAddr)
 {
     Index        = index;
     Class        = tagClass;
     MetaLocation = metaLocation;
     VirtualAddr  = virtualAddr;
 }
Ejemplo n.º 8
0
 private void FixShaderReferences(DataBlock block, IStream stream, SegmentPointer baseOffset)
 {
     foreach (DataBlockShaderFixup fixup in block.ShaderFixups)
     {
         stream.SeekTo(baseOffset.AsOffset() + fixup.WriteOffset);
         _cacheFile.ShaderStreamer.ImportShader(fixup.Data, stream);
     }
 }
Ejemplo n.º 9
0
 public SecondGenTag(DatumIndex index, ITagGroup tagGroup, SegmentPointer metaLocation, int size)
 {
     Index        = index;
     Group        = tagGroup;
     MetaLocation = metaLocation;
     Offset       = (int)MetaLocation.AsPointer();
     DataSize     = size;
 }
Ejemplo n.º 10
0
        private void WriteDataBlock(DataBlock block, SegmentPointer location, IStream stream, ITag tag = null)
        {
            if (tag == null && _dataBlockAddresses.ContainsKey(block))             // Don't write anything if the block has already been written
            {
                return;
            }

            // Associate the location with the block
            _dataBlockAddresses[block] = location.AsPointer();

            // Create a MemoryStream and write the block data to it (so fixups can be performed before writing it to the file)
            using (var buffer = new MemoryStream(block.Data.Length))
            {
                var bufferWriter = new EndianWriter(buffer, stream.Endianness);
                bufferWriter.WriteBlock(block.Data);

                // Apply fixups
                FixBlockReferences(block, bufferWriter, stream);
                FixTagReferences(block, bufferWriter, stream);
                FixResourceReferences(block, bufferWriter, stream);
                FixStringIdReferences(block, bufferWriter);
                if (tag != null)
                {
                    FixUnicListReferences(block, tag, bufferWriter, stream);
                }
                FixModelDataReferences(block, bufferWriter, stream, location);
                FixEffectReferences(block, bufferWriter);

                // sort after fixups
                if (block.Sortable && block.EntrySize >= 4)
                {
                    var entries      = new List <Tuple <uint, byte[]> >();
                    var bufferReader = new EndianReader(buffer, stream.Endianness);

                    for (int i = 0; i < block.EntryCount; i++)
                    {
                        buffer.Position = i * block.EntrySize;
                        uint   sid  = bufferReader.ReadUInt32();
                        byte[] rest = bufferReader.ReadBlock(block.EntrySize - 4);
                        entries.Add(new Tuple <uint, byte[]>(sid, rest));
                    }
                    buffer.Position = 0;
                    foreach (var entry in entries.OrderBy(e => e.Item1))
                    {
                        bufferWriter.WriteUInt32(entry.Item1);
                        bufferWriter.WriteBlock(entry.Item2);
                    }
                }

                // Write the buffer to the file
                stream.SeekTo(location.AsOffset());
                stream.WriteBlock(buffer.ToArray(), 0, (int)buffer.Length);
            }

            // Write shader fixups (they can't be done in-memory because they require cache file expansion)
            FixShaderReferences(block, stream, location);
        }
Ejemplo n.º 11
0
        public NewThirdGenTagTable(IReader reader, SegmentPointer indexHeaderLocation, FileSegmentGroup metaArea,
                                   MetaAllocator allocator, EngineDescription buildInfo)
        {
            _indexHeaderLocation = indexHeaderLocation;
            _metaArea            = metaArea;
            _allocator           = allocator;
            _buildInfo           = buildInfo;

            Load(reader);
        }
Ejemplo n.º 12
0
        private Partition[] LoadPartitions(StructureValueCollection[] partitionValues)
        {
            IEnumerable <Partition> result = from partition in partitionValues
                                             select new Partition
                                             (
                partition.GetInteger("load address") != 0
                                                ? SegmentPointer.FromPointer((long)partition.GetInteger("load address"), MetaArea)
                                                : null,
                (uint)partition.GetInteger("size")
                                             );

            return(result.ToArray());
        }
Ejemplo n.º 13
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="DataBlockBuilder" /> class.
        /// </summary>
        /// <param name="reader">The stream to read from.</param>
        /// <param name="tagLocation">The location of the tag to load data blocks for.</param>
        /// <param name="cacheFile">The cache file.</param>
        /// <param name="buildInfo">The build info for the cache file.</param>
        public DataBlockBuilder(IReader reader, SegmentPointer tagLocation, ICacheFile cacheFile, EngineDescription buildInfo)
        {
            _reader          = reader;
            _tagLocation     = tagLocation;
            _cacheFile       = cacheFile;
            _tagRefLayout    = buildInfo.Layouts.GetLayout("tag reference");
            _reflexiveLayout = buildInfo.Layouts.GetLayout("reflexive");
            _dataRefLayout   = buildInfo.Layouts.GetLayout("data reference");

            DataBlocks          = new List <DataBlock>();
            ReferencedTags      = new HashSet <DatumIndex>();
            ReferencedResources = new HashSet <DatumIndex>();
        }
Ejemplo n.º 14
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;

            // TODO (Dragon): hack for h2 alpha
            if (BuildString == "02.01.07.4998")
            {
                metaSize = (int)values.GetInteger("tag data offset") + (int)values.GetInteger("tag data size");
                // hack to rewrite the "meta size" value even though its not actually the meta size
                //_saved_meta_size_hack = (uint)values.GetInteger("meta size");
            }
            else
            {
                metaSize = (int)values.GetInteger("meta size");
            }

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

            // we hacked in a meta header size into the values earlier in the cache load
            uint 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));

            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);

            // dummy stringids
            StringIDCount      = 0;
            StringIDData       = _eofSegment;
            StringIDIndexTable = _eofSegment;
        }
Ejemplo n.º 15
0
        /*
         *      private void AdjustPartitions()
         *      {
         *              if (MetaArea == null)
         *                      return;
         *
         *              // Find the first partition with a non-null address and change it to the meta area's base address
         *              Partition partition = Partitions.First(p => p.BasePointer != null);
         *              if (partition != null)
         *                      partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea);
         *
         *              // Recalculate the size of each partition
         *              int partitionEnd = MetaArea.Offset + MetaArea.Size;
         *              for (int i = Partitions.Length - 1; i >= 0; i--)
         *              {
         *                      if (Partitions[i].BasePointer == null)
         *                              continue;
         *
         *                      int offset = Partitions[i].BasePointer.AsOffset();
         *                      Partitions[i].Size = (uint) (partitionEnd - offset);
         *                      partitionEnd = offset;
         *              }
         *      }
         */

        /*
         *      private StructureValueCollection[] SerializePartitions()
         *      {
         *              if (Partitions == null)
         *                      return new StructureValueCollection[0];
         *
         *              var results = new StructureValueCollection[Partitions.Length];
         *              for (int i = 0; i < Partitions.Length; i++)
         *              {
         *                      var values = new StructureValueCollection();
         *                      values.SetInteger("load address", Partitions[i].BasePointer != null ? Partitions[i].BasePointer.AsPointer() : 0);
         *                      values.SetInteger("size", Partitions[i].Size);
         *                      results[i] = values;
         *              }
         *              return results;
         *      }
         */

        /// <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)
         *      {
         *
         *              FourthGenInteropSection debugSection = Sections[(int) FourthGenInteropSectionType.Debug];
         *              FourthGenInteropSection rsrcSection = Sections[(int) FourthGenInteropSectionType.Resource];
         *              FourthGenInteropSection tagSection = Sections[(int) FourthGenInteropSectionType.Tag];
         *              FourthGenInteropSection localeSection = Sections[(int) FourthGenInteropSectionType.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 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) FourthGenInteropSectionType.Debug] != 0)
         *                      debugSection.VirtualAddress -= Partitions[0].Size;
         *
         *              // Recompute offset masks
         *              SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] = (debugSection.Size > 0)
         *                      ? (uint) (StringArea.Offset - debugSection.VirtualAddress)
         *                      : 0;
         *              SectionOffsetMasks[(int) FourthGenInteropSectionType.Resource] = (rsrcSection.Size > 0)
         *                      ? (uint) (RawTable.Offset - rsrcSection.VirtualAddress)
         *                      : 0;
         *              SectionOffsetMasks[(int) FourthGenInteropSectionType.Tag] = (tagSection.Size > 0)
         *                      ? (uint) (MetaArea.Offset - tagSection.VirtualAddress)
         *                      : 0;
         *              SectionOffsetMasks[(int) FourthGenInteropSectionType.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;
         *      }
         */

        private void Load(StructureValueCollection map_values, StructureValueCollection tag_values, StructureValueCollection string_values, FileSegmenter map_segmenter)
        {
            map_segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header
            _eofSegment = map_segmenter.WrapEOF((int)map_values.GetInteger("file size"));



            //LoadInteropData(map_values, tag_values);
            //RawTable = CalculateRawTableSegment(segmenter);

            Type         = (CacheFileType)map_values.GetInteger("type");
            InternalName = map_values.GetString("internal name");
            ScenarioPath = map_values.GetString("scenario path");

            uint index_header_address = map_values.GetInteger("index header address");

            // File Segment
            FileSegmenter tags_segmenter = new FileSegmenter();

            tags_segmenter.DefineSegment(0, (int)EngineInfo.TagsDataSize, 0x1, SegmentResizeOrigin.Beginning); // Define a segment for the header
            FileSegment metaSegment = new FileSegment(0, tags_segmenter);

            //FileSegment metaSegment = CalculateTagDataSegment(tag_values, segmenter);
            MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, index_header_address));
            MetaArea.AddSegment(metaSegment);
            IndexHeaderLocation = SegmentPointer.FromPointer(index_header_address, MetaArea);

            //XDKVersion = (int) values.GetInteger("xdk version");

            /*
             *          FileSegment metaSegment = CalculateTagDataSegment(values, segmenter);
             *          if (metaSegment != null)
             *          {
             *                  uint virtualBase = values.GetInteger("virtual base address");
             *                  MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, virtualBase));
             *                  MetaArea.AddSegment(metaSegment);
             *
             *                  IndexHeaderLocation = SegmentPointer.FromPointer(values.GetInteger("index header address"), MetaArea);
             *                  Partitions = LoadPartitions(values.GetArray("partitions"));
             *          }
             *          else
             *          {
             *                  Partitions = new Partition[0];
             *          }
             */
            CalculateStringGroup(string_values, map_segmenter);
        }
Ejemplo n.º 16
0
        /// <summary>
        ///     Adds a tag to the table and allocates space for its base data.
        /// </summary>
        /// <param name="classMagic">The magic number (ID) of the tag's class.</param>
        /// <param name="baseSize">The size of the data to initially allocate for the tag.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <returns>
        ///     The tag that was allocated.
        /// </returns>
        public override ITag AddTag(int classMagic, int baseSize, IStream stream)
        {
            /*
             *          //if (_indexHeaderLocation == null)
             *          //	throw new InvalidOperationException("Tags cannot be added to a shared map");
             *
             *          ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));
             *          if (tagClass == null)
             *                  throw new InvalidOperationException("Invalid tag class");
             *
             *          uint address = _allocator.Allocate(baseSize, stream);
             *          var index = new DatumIndex(0x4153, (ushort) _tags.Count); // 0x4153 = 'AS' because the salt doesn't matter
             * var result = new FourthGenTag(index, tagClass, (uint)stream.Position);
             *          _tags.Add(result);
             *
             *          return result;
             * */

            ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));

            if (tagClass == null)
            {
                throw new InvalidOperationException("Invalid tag class");
            }

            var  offset  = stream.BaseStream.Position;
            uint address = _allocator.Allocate(baseSize, stream);
            var  index   = new DatumIndex(0x4153, (ushort)_tags.Count); // 0x4153 = 'AS' because the salt doesn't matter

            // File Segment
            FileSegmenter segmenter = new FileSegmenter();

            segmenter.DefineSegment(0, (int)stream.Length, 0x4, SegmentResizeOrigin.Beginning); // Define a segment for the header
            //_eofSegment = segmenter.WrapEOF((int)map_values.GetInteger("file size"));
            FileSegment      segment      = new FileSegment(0, segmenter);
            FileSegmentGroup segmentgroup = new FileSegmentGroup();

            SegmentPointer pointer = new SegmentPointer(segment, segmentgroup, (int)offset);
            FourthGenTag   result  = new FourthGenTag(index, tagClass, pointer, pointer);

            _tags.Add(result);

            return(result);
        }
Ejemplo n.º 17
0
        private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagGroup> groupsById)
        {
            Offset = (int)values.GetInteger("offset");
            if (Offset > 0)
            {
                MetaLocation = SegmentPointer.FromPointer(Offset, metaArea);
            }

            // Load the tag group by looking up the magic value that's stored
            var groupMagic = (int)values.GetInteger("tag group magic");

            if (groupMagic != -1)
            {
                Group = groupsById[groupMagic];
            }

            Index    = new DatumIndex(values.GetInteger("datum index"));
            DataSize = (int)values.GetInteger("data size");
        }
Ejemplo n.º 18
0
		private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList<ITagGroup> groupList, IPointerExpander expander)
		{
			uint address = (uint)values.GetInteger("memory address");
			if (address != 0 && address != 0xFFFFFFFF)
			{
				long expanded = expander.Expand(address);

				MetaLocation = SegmentPointer.FromPointer(expanded, metaArea);
			}

			var groupIndex = (int) values.GetInteger("tag group index");
			if (groupIndex >= 0 && groupIndex < groupList.Count)
				Group = groupList[groupIndex];

			var salt = (ushort) values.GetInteger("datum index salt");
			if (salt != 0xFFFF)
				Index = new DatumIndex(salt, index);
			else
				Index = DatumIndex.Null;
		}
Ejemplo n.º 19
0
        private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagClass> classesById)
        {
            uint offset = values.GetInteger("offset");

            if (offset > 0)
            {
                MetaLocation = SegmentPointer.FromPointer(offset, metaArea);
            }

            // Load the tag class by looking up the magic value that's stored
            var classMagic = (int)values.GetInteger("class magic");

            if (classMagic != -1)
            {
                Class = classesById[classMagic];
            }

            Index    = new DatumIndex(values.GetInteger("datum index"));
            DataSize = (int)values.GetInteger("data size");
        }
Ejemplo n.º 20
0
        private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary <int, ITagGroup> groupsById)
        {
            // Load the tag group by looking up the magic value that's stored
            var groupMagic = (int)values.GetInteger("tag group magic");

            if (groupMagic != -1)
            {
                Group = groupsById[groupMagic];
            }

            Index = new DatumIndex(values.GetInteger("datum index"));

            // NOTE: cant really split filenames into a segment
            //       because offset is relative to the meta header
            uint nameOffset = (uint)values.GetInteger("name offset");

            if (nameOffset > 0)
            {
                FileNameOffset = SegmentPointer.FromPointer(nameOffset, metaArea);
            }
            //FileNameOffset = SegmentPointer.FromOffset((int)nameOffset, metaArea);

            uint offset = (uint)values.GetInteger("offset");

            // checking the meta area contains the offset
            // and that the tag element is not pointing to a data file
            if (offset > 0 && metaArea.ContainsPointer(offset) &&
                (values.GetInteger("is in data file") != 1))
            {
                MetaLocation = SegmentPointer.FromPointer(offset, metaArea);
            }
            // TODO (Dragon): the offset can actually be 0 when used
            //                as a data file table index
            //else if (offset > 0 && !metaArea.ContainsPointer(offset))
            // TODO (Dragon): load the tag from a data file
            //                bitm: bitmaps.map
            //                font: loc.map
            //                ustr: loc.map
            //                hmt : loc.map
        }
Ejemplo n.º 21
0
        public long InjectDataBlock(DataBlock block, IStream stream)
        {
            if (block == null)
            {
                throw new ArgumentNullException("block is null");
            }

            // Don't inject the block if it's already been injected
            long newAddress;

            if (_dataBlockAddresses.TryGetValue(block, out newAddress))
            {
                return(newAddress);
            }

            // Allocate space for it and write it to the file
            newAddress = _cacheFile.Allocator.Allocate(block.Data.Length, (uint)block.Alignment, stream);
            SegmentPointer location = SegmentPointer.FromPointer(newAddress, _cacheFile.MetaArea);

            WriteDataBlock(block, location, stream);
            return(newAddress);
        }
Ejemplo n.º 22
0
        /// <summary>
        ///     Adds a tag to the table and allocates space for its base data.
        /// </summary>
        /// <param name="classMagic">The magic number (ID) of the tag's class.</param>
        /// <param name="baseSize">The size of the data to initially allocate for the tag.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <returns>
        ///     The tag that was allocated.
        /// </returns>
        public override ITag AddTag(int classMagic, int baseSize, IStream stream)
        {
            if (_indexHeaderLocation == null)
            {
                throw new InvalidOperationException("Tags cannot be added to a shared map");
            }

            ITagClass tagClass = Classes.FirstOrDefault(c => (c.Magic == classMagic));

            if (tagClass == null)
            {
                throw new InvalidOperationException("Invalid tag class");
            }

            uint address = _allocator.Allocate(baseSize, stream);
            var  index   = new DatumIndex(0x4153, (ushort)_tags.Count);           // 0x4153 = 'AS' because the salt doesn't matter
            var  result  = new ThirdGenTag(index, tagClass, SegmentPointer.FromPointer(address, _metaArea));

            _tags.Add(result);

            return(result);
        }
Ejemplo n.º 23
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.º 24
0
        private void Load(StructureValueCollection values, FileSegmenter segmenter)
        {
            _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size"));

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

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

            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));

            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");

            RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 1, SegmentResizeOrigin.End);

            Checksum = 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.º 25
0
 /// <summary>
 ///     Creates a new Partition object, given a base pointer and a size.
 /// </summary>
 /// <param name="basePointer">The pointer to the start of the partition.</param>
 /// <param name="size">The partition's size.</param>
 public Partition(SegmentPointer basePointer, uint size)
 {
     BasePointer = basePointer;
     Size        = size;
 }
Ejemplo n.º 26
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);

            //xbox haxx, we can assume thru the existance of the code-set xbox mask
            uint        metaOffsetMask;
            FileSegment metaSegment = null;

            if (values.HasInteger("xbox meta offset mask"))
            {
                // 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");

                metaOffsetMask = (uint)values.GetInteger("xbox meta offset mask");

                metaSegment = new FileSegment(
                    segmenter.DefineSegment(metaOffset + tagTableSize, tagDataSize, 0x4, SegmentResizeOrigin.End), segmenter);
            }
            else
            {
                metaOffsetMask = (uint)values.GetInteger("meta offset mask");

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

            MetaArea = new FileSegmentGroup(new MetaOffsetConverter(headSegment, 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);

            if (values.HasInteger("file table count"))
            {
                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();
            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);

            if (FileNameIndexTable != null)
            {
                StringArea.AddSegment(FileNameIndexTable);
                StringArea.AddSegment(FileNameData);

                FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea);
                FileNameDataLocation       = SegmentPointer.FromOffset(FileNameData.Offset, StringArea);
            }

            int rawTableOffset;
            int rawTableSize;

            if (values.HasInteger("raw table offset"))
            {
                rawTableOffset = (int)values.GetInteger("raw table offset");
                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.º 27
0
        private List <ITag> LoadTags(IReader reader, StructureValueCollection headerValues, IList <ITagClass> classes)
        {
            /*
             * StructureLayout layout = _buildInfo.Layouts.GetLayout("tag entry");
             *          StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, count, address, layout, _metaArea);
             *          return
             *                  entries.Select<StructureValueCollection, ITag>((e, i) => new FourthGenTag(e, (ushort) i, _metaArea, classes))
             *                          .ToList();
             */

            List <ITag> tags = new List <ITag>(); // New list of tags

            reader.SeekTo(0);
            var             count   = (int)headerValues.GetInteger("number of tags");
            uint            address = headerValues.GetInteger("tag table address");
            StructureLayout layout  = _buildInfo.Layouts.GetLayout("tag entry");

            // File Segment
            FileSegmenter segmenter = new FileSegmenter();

            segmenter.DefineSegment(0, (int)reader.Length, 0x4, SegmentResizeOrigin.Beginning); // Define a segment for the header
            //_eofSegment = segmenter.WrapEOF((int)map_values.GetInteger("file size"));
            FileSegment      segment      = new FileSegment(0, segmenter);
            FileSegmentGroup segmentgroup = new FileSegmentGroup();

            // Find all of the tag offsets
            reader.BaseStream.Position = address; // Start at the beginning og the offsets
            List <uint> tagOffsets = new List <uint>();

            for (int i = 0; i < count; i++)
            {
                tagOffsets.Add(reader.ReadUInt32());
            }

            reader.BaseStream.Position = tagOffsets[0];
            for (int i = 0; i < count; i++) // Loop through each offset
            {
                //if (tagOffsets[i] == 0) tags.Add(null);
                //else
                if (tagOffsets[i] != 0)
                {
                    //var headerOffset = (uint)reader.BaseStream.Position;

                    /*
                     * 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 = reader.ReadInt32();                          // 0x14 int32  class
                     * var parentClass = reader.ReadInt32();                       // 0x18 int32  parent class
                     * var grandparentClass = reader.ReadInt32();                  // 0x1C int32  grandparent class
                     * var classId = reader.ReadUInt32();                          // 0x20 uint32 class stringid
                     */
                    /*
                     *
                     * reader.BaseStream.Position = tagOffsets[i];
                     * StructureValueCollection tag_entry_values = StructureReader.ReadStructure(reader, layout);
                     * uint id = tag_entry_values.GetInteger("magic");
                     * if(id == 0x3c66783e )
                     * {
                     *  uint x = id;
                     * }
                     * //ITagClass tagclass = TryAddClass(tag_entry_values);
                     * //FourthGenTag tag = new FourthGenTag(new DatumIndex(headerOffset), tagclass, headerOffset);
                     *
                     * uint tag_offset = tagOffsets[i];
                     * //SegmentPointer pointer = new SegmentPointer(segment, segmentgroup, (int)tag_offset);
                     *
                     * uint dep_size = (tag_entry_values.GetInteger("dependencies count") * 4 + tag_entry_values.GetInteger("data fixups count") * 4 + tag_entry_values.GetInteger("resource fixups count") * 4);
                     * tag_offset += tag_entry_values.GetInteger("total size") - (tag_entry_values.GetInteger("main struct offset") + dep_size);
                     *
                     * ITagClass tagclass = TryAddClass(tag_entry_values);
                     * //FourthGenTag tag = new FourthGenTag(new DatumIndex(headerOffset), tagclass, headerOffset);
                     *
                     * SegmentPointer pointer = new SegmentPointer(segment, segmentgroup, (int)(tag_offset));
                     *
                     * FourthGenTag tag = new FourthGenTag(new DatumIndex(tag_offset), tagclass, pointer);
                     * tags.Add(tag);
                     * */

                    var headerOffset = tagOffsets[i];
                    reader.BaseStream.Position = headerOffset;

                    StructureValueCollection tag_entry_values = StructureReader.ReadStructure(reader, layout);

                    reader.BaseStream.Position = tagOffsets[i] + 0x24;

                    int structOffset = (int)tag_entry_values.GetInteger("main struct offset");
                    int metaOffset   = (int)tagOffsets[i] + structOffset;

                    ITagClass tagclass = TryAddClass(tag_entry_values);

                    //SegmentPointer pointer = new SegmentPointer(segment, segmentgroup, metaOffset);
                    //FourthGenTag tag = new FourthGenTag(new DatumIndex((uint)i), tagclass, pointer);
                    SegmentPointer hdrPointer = new SegmentPointer(segment, segmentgroup, (int)headerOffset);
                    SegmentPointer pointer    = new SegmentPointer(segment, segmentgroup, metaOffset);
                    FourthGenTag   tag        = new FourthGenTag(new DatumIndex((uint)i), tagclass, hdrPointer, pointer);
                    tags.Add(tag);
                }
                else // Null Tag
                {
                    FourthGenTag tag = new FourthGenTag(new DatumIndex((uint)i), null, null, null);
                    tags.Add(tag);
                }
            }

            return(tags.Where(t => t != null).ToList()); // Remove NULL Entries
        }
Ejemplo n.º 28
0
		public ThirdGenTag(DatumIndex index, ITagGroup tagGroup, SegmentPointer metaLocation)
		{
			Index = index;
			Group = tagGroup;
			MetaLocation = metaLocation;
		}
Ejemplo n.º 29
0
        private void FixInteropReferences(DataBlock block, IWriter buffer, IStream stream, SegmentPointer location)
        {
            foreach (DataBlockInteropFixup fixup in block.InteropFixups)
            {
                long newAddress = InjectDataBlock(fixup.OriginalAddress, stream);

                uint cont = _cacheFile.PointerExpander.Contract(newAddress);

                buffer.SeekTo(fixup.WriteOffset);
                buffer.WriteUInt32(cont);

                uint contp = _cacheFile.PointerExpander.Contract(location.AsPointer() + fixup.WriteOffset);

                _cacheFile.TagInteropTable.Add(new Blam.ThirdGen.Structures.ThirdGenTagInterop(contp, fixup.Type));
            }
        }
Ejemplo n.º 30
0
 public ThirdGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer metaLocation)
 {
     Index        = index;
     Class        = tagClass;
     MetaLocation = metaLocation;
 }