Exemplo n.º 1
0
        /// <summary>
        ///     Copies the paths from the Index into the given stream at the current address
        ///     note: Creates the table on an align(512) address then creates the table-index on
        ///     an align(512) address following it.
        /// </summary>
        /// <param name="outputStream">The stream to write to</param>
        /// <returns>PathInfoStruct containing addresses/info of the paths table & index</returns>
        private PathsInfoStruct GeneratePathsTable(Stream outputStream)
        {
            var info = new PathsInfoStruct( );
            //  extract the paths from the index and copy them into a local list object.
            var paths = Index.Select(x => x.Path).ToList( );

            info.PathCount        = paths.Count;
            info.PathTableAddress = outputStream.Align(512);
            //  pad the stream to align(512) and assign the new address to PathTableAddress.
            GenerateStringEntries(outputStream, paths);
            //  Write the paths into the stream and subtract the PathTableAddress from the new stream position
            //  to get the PathTableLength.
            info.PathTableLength = ( int )outputStream.Position - info.PathTableAddress;
            //  pad the stream to align(512) and assign the new address to PathIndexAddress.
            info.PathIndexAddress = outputStream.Align(512);
            //  write the index for the path table
            GenerateTableIndex(outputStream, paths);

            //  finish on the next 512 alignment boundary
            outputStream.Align(512);
            Padding.AssertIsAligned(512, outputStream);
            //  return the struct that contains the information about where in the stream this
            //  resource was written
            return(info);
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 3
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;
        }
Exemplo n.º 4
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);
        }