Example #1
0
        public ThirdGenTagTable(IReader reader, SegmentPointer indexHeaderLocation, FileSegmentGroup metaArea,
			MetaAllocator allocator, EngineDescription buildInfo)
        {
            _indexHeaderLocation = indexHeaderLocation;
            _metaArea = metaArea;
            _allocator = allocator;
            _buildInfo = buildInfo;

            Load(reader);
        }
Example #2
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>();
        }
Example #3
0
        void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList<ITagClass> classList)
        {
            uint address = values.GetInteger("memory address");
            if (address != 0 && address != 0xFFFFFFFF)
            {
                int classIndex = (int)values.GetInteger("class index");
                Class = classList[classIndex];

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

                MetaLocation = SegmentPointer.FromPointer(address, metaArea);
            }
        }
Example #4
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 #5
0
        /// <summary>
        ///     Adds a segment to the group.
        /// </summary>
        /// <param name="segment">The segment to add.</param>
        /// <returns>A SegmentPointer pointing to the beginning of the segment.</returns>
        public SegmentPointer AddSegment(FileSegment segment)
        {
            int offset = segment.Offset;

            if (_segmentsByOffset.ContainsKey(offset))
            {
                throw new ArgumentException("A segment has already been added at the given offset.");
            }

            _segmentsByOffset[segment.Offset] = segment;
            segment.Resized += SegmentResized;

            return(SegmentPointer.FromOffset(segment.Offset, this));
        }
Example #6
0
        public void ReadRequestedStrings(IReader reader, SegmentPointer baseLocation, CachedStringTable output)
        {
            int baseOffset = baseLocation.AsOffset();

            int lastEnd = -1;
            foreach (int offset in _requestedStrings)
            {
                if (offset <= lastEnd)
                    continue;
                reader.SeekTo(baseOffset + offset);
                string str = reader.ReadAscii();
                output.CacheString(offset, str);
                lastEnd = offset + str.Length;
            }
        }
Example #7
0
        private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList<ITagClass> classList)
        {
            uint address = values.GetInteger("memory 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;
        }
		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);
			}
		}
		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);

				// 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, location);
		}
Example #10
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;
 }
Example #11
0
		public FourthGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer headerLocation, SegmentPointer metaLocation)
		{
			Index = index;
			Class = tagClass;
			MetaLocation = metaLocation;
			HeaderLocation = headerLocation;
		}
Example #12
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);
            }
        }
Example #13
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
		}
Example #14
0
 public ThirdGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer metaLocation)
 {
     Index = index;
     Class = tagClass;
     MetaLocation = metaLocation;
 }
        private List<IScript> LoadScripts(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, ExpressionTable expressions, StructureLayout entryLayout, BuildInformation buildInfo)
        {
            int scriptCount = (int)values.GetInteger("number of scripts");
            if (scriptCount == 0)
                return new List<IScript>();

            ScriptsLocation = SegmentPointer.FromPointer(values.GetInteger("script table address"), metaArea);

            // Read all of the script entries first, then go back and create the objects
            // ThirdGenScript reads parameters from its constructor - this may or may not need cleaning up to make this more obvious
            reader.SeekTo(ScriptsLocation.AsOffset());
            List<StructureValueCollection> scriptData = new List<StructureValueCollection>();
            for (int i = 0; i < scriptCount; i++)
                scriptData.Add(StructureReader.ReadStructure(reader, entryLayout));

            List<IScript> result = new List<IScript>();
            foreach (StructureValueCollection scriptValues in scriptData)
                result.Add(new ThirdGenScript(reader, scriptValues, metaArea, stringIDs, expressions, buildInfo));
            return result;
        }
Example #16
0
        private List<ITag> ReadTags(IReader reader, SegmentPointer tagTableLocation, int numTags, BuildInformation buildInfo, FileSegmentGroup metaArea)
        {
            StructureLayout layout = buildInfo.GetLayout("tag entry");

            List<ITag> result = new List<ITag>();
            reader.SeekTo(tagTableLocation.AsOffset());
            for (int i = 0; i < numTags; i++)
            {
                StructureValueCollection values = StructureReader.ReadStructure(reader, layout);
                result.Add(new ThirdGenTag(values, (ushort)i, metaArea, _classes));
            }
            return result;
        }
Example #17
0
        private List<ITagClass> ReadClasses(IReader reader, SegmentPointer classTableLocation, int numClasses, BuildInformation buildInfo)
        {
            StructureLayout layout = buildInfo.GetLayout("class entry");

            List<ITagClass> result = new List<ITagClass>();
            reader.SeekTo(classTableLocation.AsOffset());
            for (int i = 0; i < numClasses; i++)
            {
                StructureValueCollection values = StructureReader.ReadStructure(reader, layout);
                result.Add(new ThirdGenTagClass(values));
            }
            return result;
        }
Example #18
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;
		}