private void Allocate(TagIdent ident, int size) { //create virtual stream to write into var tagCacheStream = new VirtualStream(Index[Index.GlobalsIdent].VirtualAddress); var binaryWriter = new BinaryWriter(tagCacheStream); for (var i = 0; i < Index.Count; ++i) { var datum = Index[i]; // is this address affected by the shift? if (datum.Identifier == ident) { var alignment = Guerilla.Guerilla.AlignmentOf(Halo2.GetTypeOf(Index[ident].Class)); datum.VirtualAddress = binaryWriter.BaseStream.Align(alignment); binaryWriter.Write(new byte[size]); datum.Length = size; Index.Update(datum.Identifier, datum); } else { var data = Deserialize(datum.Identifier); var length = binaryWriter.BaseStream.Length; binaryWriter.Write(data); binaryWriter.Seek(0, SeekOrigin.End); length = (int)binaryWriter.BaseStream.Length - length; datum.Length = (int)length; Index.Update(datum.Identifier, datum); } } binaryWriter.WritePadding(512); }
public TagDatum Add <T>(T item, string tagName) where T : GuerillaBlock { var lastDatum = Index.Last(); var stream = new VirtualStream(lastDatum.VirtualAddress); var binaryWriter = new BinaryWriter(stream); binaryWriter.Write(item); var serializedTagData = stream.ToArray(); var attribute = ( TagClassAttribute )item.GetType( ).Attribute(typeof(TagClassAttribute)) ?? ( TagClassAttribute ) item.GetType( ).BaseType?.GetCustomAttributes(typeof(TagClassAttribute)).FirstOrDefault(); var tagDatum = Index.Add(attribute.TagClass, tagName, serializedTagData.Length, lastDatum.VirtualAddress); _deserializedTagCache.Add(tagDatum.Identifier, item); var paths = Index.Select(x => x.Path); #if DEBUG //new Validator().Validate(tagDatum, stream); #endif return(tagDatum); //Allocate(tagDatum.Identifier, serializedTagData.Length); }
private void CopyMeta(Stream outputStream, int address, out int metaDataSize) { var startAddress = outputStream.Align(512); var buffer = new VirtualStream(address); for (var i = 0; i < Index.Count; ++i) { var datum = Index[i]; if (datum.Class == TagClass.Sbsp || datum.Class == TagClass.Ltmp) { datum.Length = 0; datum.VirtualAddress = 0; Index.Update(datum.Identifier, datum); continue; } var data = Deserialize(datum.Identifier); var dataAddress = ( int )buffer.Position; Padding.AssertIsAligned(4, buffer); buffer.Write(data); buffer.Align( ); var length = ( int )buffer.Position - dataAddress; datum.Length = length; datum.VirtualAddress = dataAddress; Index.Update(datum.Identifier, datum); } buffer.Position = 0; buffer.BufferedCopyBytesTo(( int )buffer.Length, outputStream); metaDataSize = outputStream.Align(4096) - startAddress; }
public void SerializeTo(Stream outputStream) { // Calculate size of arrays var sizeOfTagClassHeirarchyArray = _classes.Count * TagClassHeirarchy.SizeInBytes; const int sizeOfTagDatum = 16; var sizeOfTagDatumArray = _data.Count * sizeOfTagDatum; // Create buffer and writer var buffer = new byte[GetSize() + HeaderSize]; var stream = new VirtualStream(buffer, VirtualBaseAddress); var binaryWriter = new BinaryWriter(stream); // move past the header stream.Seek(HeaderSize, SeekOrigin.Begin); // write tag-class array classArrayAddress = (int)stream.Position; classArrayCount = _classes.Count; foreach (var tagClassHeirarchy in _classes) { WriteTagHeirarchy(binaryWriter, tagClassHeirarchy); } // write tag-data array datumArrayAddress = (int)stream.Position; datumArrayCount = _data.Count; foreach (var tagDatum in _data) { WriteTagDatum(binaryWriter, tagDatum); } // Serialise header and update address var headerBytes = SerializeHeader(); stream.Seek(0, SeekOrigin.Begin); binaryWriter.Write(headerBytes); outputStream.Write(buffer, 0, buffer.Length); }
private int CopyStructureMeta(Stream outputStream) { var allocationLength = 0; var scnrBlock = ( ScenarioBlock )Deserialize(Index.ScenarioIdent); var buffer = new byte[0x2000000]; // 32 mebibytes foreach (var scenarioStructureBspReferenceBlock in scnrBlock.StructureBSPs) { // create a virtual stream to write the meta into and assign the origin address // of the first valid memory after the index // // note: the virtual stream is used to generate valid pointer addressess var allocationAddress = VirtualBaseAddress + Index.GetSize( ) + TagIndexBase.HeaderSize; var virtualMemoryStream = new VirtualStream(buffer, allocationAddress); var sbspReference = scenarioStructureBspReferenceBlock.StructureBSP; var ltmpReference = scenarioStructureBspReferenceBlock.StructureLightmap; // if both references are null then we don't copy out the meta if (TagIdent.IsNull(ltmpReference.Ident) && TagIdent.IsNull(sbspReference.Ident)) { continue; } virtualMemoryStream.Write(new byte[16], 0, 16); // create an allocation header to hold information about this memory allocation var structureAllocationHeader = new StructureAllocationHeader { StructureBSPAddress = ( int )virtualMemoryStream.Position, FourCC = TagClass.Sbsp }; // grab the structurebsp from the cache and write it out to the virtual stream, // padding it to 4 byte alignement var sbspBlock = ( ScenarioStructureBspBlock )Deserialize(sbspReference.Ident); virtualMemoryStream.Write(sbspBlock); virtualMemoryStream.Align( ); // if the lightmap is not null write out the meta data into the virtual stream if (!TagIdent.IsNull(ltmpReference.Ident)) { structureAllocationHeader.LightmapAddress = ( int )virtualMemoryStream.Position; var ltmpBlock = ( ScenarioStructureLightmapBlock )Deserialize(ltmpReference.Ident); virtualMemoryStream.Write(ltmpBlock); } structureAllocationHeader.BlockLength = Padding.Align( virtualMemoryStream.Position - allocationAddress, 4096); // set the value of BlockLength to the length of the virtual stream, // then serialize and write the header to the output stream, followed by writing // the contents of the vitual stream to the output stream // finally pad the entire thing to 4096 byte alignment // copy data virtualMemoryStream.Seek(0, SeekOrigin.Begin); structureAllocationHeader.SerializeTo(virtualMemoryStream); virtualMemoryStream.Seek(-StructureAllocationHeader.SizeInBytes, SeekOrigin.Current); scenarioStructureBspReferenceBlock.StructureBlockInfo.BlockOffset = ( int )outputStream.Position; Padding.AssertIsAligned(512, outputStream); virtualMemoryStream.BufferedCopyBytesTo(structureAllocationHeader.BlockLength, outputStream); Padding.AssertIsAligned(512, outputStream); scenarioStructureBspReferenceBlock.StructureBlockInfo.BlockAddress = allocationAddress; scenarioStructureBspReferenceBlock.StructureBlockInfo.BlockLength = structureAllocationHeader.BlockLength; // return only the largest allocation size, because all allocations are in the // same virtual memory allocationLength = allocationLength > structureAllocationHeader.BlockLength ? allocationLength : structureAllocationHeader.BlockLength; } return(allocationLength); }