Example #1
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");
        }
Example #2
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;
            }
        }
Example #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;
            }
        }
Example #5
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());
        }
        /*
         *      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);
        }
Example #7
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");
        }
Example #8
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");
        }
Example #9
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;
		}
Example #10
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
        }
        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);
        }
Example #12
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);
        }