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