예제 #1
0
        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;
        }
예제 #2
0
        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);
        }