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());
        }
 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);
     }
 }
Beispiel #3
0
        private StructureValueCollection LoadHeader(IReader reader)
        {
            if (_indexHeaderLocation == null)
            {
                return(null);
            }

            reader.SeekTo(_indexHeaderLocation.AsOffset());
            StructureLayout          headerLayout = _buildInfo.Layouts.GetLayout("index header");
            StructureValueCollection result       = StructureReader.ReadStructure(reader, headerLayout);

            if (result.GetInteger("magic") != CharConstant.FromString("tags"))
            {
                throw new ArgumentException("Invalid index table header magic");
            }

            return(result);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        public bool EnterPlugin(int baseSize)
        {
            // Read the tag data in based off the base size
            _reader.SeekTo(_tagLocation.AsOffset());
            byte[] data = _reader.ReadBlock(baseSize);

            // Create a block for it and push it onto the block stack
            var block = new DataBlock(_tagLocation.AsPointer(), 1, 4, data);

            DataBlocks.Add(block);

            var blockList = new List <DataBlock>();

            blockList.Add(block);
            _blockStack.Push(blockList);

            return(true);
        }