Example #1
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());
        }
Example #2
0
 public SecondGenTag(DatumIndex index, ITagGroup tagGroup, SegmentPointer metaLocation, int size)
 {
     Index        = index;
     Group        = tagGroup;
     MetaLocation = metaLocation;
     Offset       = (int)MetaLocation.AsPointer();
     DataSize     = size;
 }
Example #3
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);
        }
        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));
            }
        }
Example #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);
        }