Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #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;
        }
Exemple #4
0
        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);
        }
Exemple #5
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);
        }