public BlamPointer(int count, int address, int elementsize, int alignment = 4) { ElementCount = count; StartAddress = Padding.Align(address, alignment); ElementSize = elementsize; _endAddress = StartAddress + ElementSize * ElementCount; }
private void CopyUnicodeTable(Stream outputStream) { var globalsBlock = ( GlobalsBlock )Deserialize(Index.GlobalsIdent); var newUnicodeBlockInfo = new MoonfishGlobalUnicodeBlockInfoStructBlock { EnglishStringCount = globalsBlock.UnicodeBlockInfo.EnglishStringCount, EnglishStringTableLength = globalsBlock.UnicodeBlockInfo.EnglishStringTableLength }; // calculate the size of the Unicode table-index & tables to the nearest 512 aligned block var alignedIndexSize = Padding.Align( globalsBlock.UnicodeBlockInfo.EnglishStringCount * sizeof(int) * 2, 512); var alignedTableSize = Padding.Align(globalsBlock.UnicodeBlockInfo.EnglishStringTableLength, 512); // move the stream to the start of the unicode data Seek(globalsBlock.UnicodeBlockInfo.EnglishStringIndexAddress, SeekOrigin.Begin); // copy the table-index and index to the output stream newUnicodeBlockInfo.EnglishStringIndexAddress = ( int )outputStream.Position; Padding.AssertIsAligned(512, outputStream); this.BufferedCopyBytesTo(alignedIndexSize, outputStream); newUnicodeBlockInfo.EnglishStringTableAddress = ( int )outputStream.Position; Padding.AssertIsAligned(512, outputStream); this.BufferedCopyBytesTo(alignedTableSize, outputStream); // assign the new UnicodeBlockInfo data to the globals block globalsBlock.UnicodeBlockInfo = newUnicodeBlockInfo; }
private void BufferElementData(ICollection <GlobalGeometrySectionStructBlock> sectionData) { var offset = 0; var indexBufferSize = sectionData.Sum(x => Padding.Align(x.StripIndices.Length * sizeof(ushort))); var indexBaseVertex = sectionData.ToDictionary(k => k, v => 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementBuffer); GL.BufferData(BufferTarget.ElementArrayBuffer, ( IntPtr )indexBufferSize, ( IntPtr )null, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _elementBuffer); foreach (var renderModelSectionDataBlock in sectionData) { var indices = renderModelSectionDataBlock.StripIndices.Select(e => e.Index).ToArray( ); var dataSize = Padding.Align(indices.Length * sizeof(ushort)); GL.BufferSubData(BufferTarget.ElementArrayBuffer, ( IntPtr )offset, ( IntPtr )dataSize, indices); indexBaseVertex[renderModelSectionDataBlock] = offset; foreach (var part in renderModelSectionDataBlock.Parts) { SetIndexOffset(part, offset); } offset += dataSize; } }
public int GetSize( ) { return (Padding.Align( _classes.Count * TagClassHeirarchy.SizeInBytes + _data.Count * TagDatum.SizeInBytes, 512)); }
private void CopyLocalResource(Stream outputStream, IResourceBlock resourceBlock, ResourcePointer address, int length, int index = 0) { // the resource has already been copied if (address < GetFilePosition( )) { // if this is true then we've already handled this resource so use the // new address ResourcePointer newAddress; if (ShiftData.TryGetValue(address, out newAddress)) { resourceBlock.SetResourcePointer(newAddress, index); return; } // has the resource already been copied? Has it been moved? // well, shit. System.Diagnostics.Debug.WriteLineIf(address < GetFilePosition( ), "Warning: address < GetFilePosition()"); this.Seek(address); } // this is not strictly an error but it should be treated as such if (address > GetFilePosition( )) { System.Diagnostics.Debug.WriteLineIf(address > GetFilePosition( ), "Warning: address > GetFilePosition()"); this.Seek(address); } System.Diagnostics.Debug.WriteLineIf(address % 512 != 0, "Warning: address % 512 != 0"); if (outputStream.Position % 512 != 0) { System.Diagnostics.Debug.WriteLineIf(outputStream.Position % 512 != 0, "Warning: output address % 512 != 0"); } var position = outputStream.Position; ShiftData[address] = ( int )position; resourceBlock.SetResourcePointer(( int )position, index); var size = Padding.Align(length, 512); this.BufferedCopyBytesTo(size, outputStream); }
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); }