Exemple #1
0
        protected NomadObject ReadMapData(BinaryStream stream)
        {
            var check = stream.ReadInt32();

            var result = new NomadObject()
            {
                Id = "FCXMapData"
            };

            if (check != 0x26)
            {
                // non-editor map?
                stream.Position -= 4;

                UID = stream.Read <Guid>();
                ReadPadding(stream, 1);

                Version   = 0;
                IsUserMap = false;
            }
            else
            {
                var magic = stream.ReadInt32();

                if (magic != MGX_MAPDATA)
                {
                    throw new InvalidDataException("Invalid FCX map data -- bad data magic!");
                }

                Version   = check;
                IsUserMap = true;

                ReadPadding(stream, 3);

                MetaData   = ReadFCBChunk(stream, result);
                ConfigData = ReadFCBChunk(stream, result);

                ReadPadding(stream, 5);

                var thumbSize = stream.ReadInt32();

                if (thumbSize > 0)
                {
                    ThumbData = stream.ReadBytes(thumbSize);
                }

                ReadPadding(stream, 1);
            }

            var mapSize = (int)(stream.Length - stream.Position);

            MapData = stream.ReadBytes(mapSize);

            return(result);
        }
Exemple #2
0
        public void Deserialize(BinaryStream stream)
        {
            var offset = stream.ReadInt32();
            var length = offset - 4;

            Data = new byte[length];

            if (stream.Read(Data, 0, length) != length)
            {
                throw new FormatException();
            }

            var blockCount = stream.ReadInt32();

            Blocks = new List <Block>();

            for (int i = 0; i < blockCount; i++)
            {
                var block = new Block()
                {
                    VirtualOffset = stream.ReadUInt32(),
                    FileOffset    = stream.ReadUInt32(),
                };

                block.IsCompressed = (block.FileOffset & 0x80000000) != 0;
                block.FileOffset  &= 0x7FFFFFFF;

                Blocks.Add(block);
            }

            if (Blocks.Count == 0)
            {
                throw new FormatException();
            }

            if (Blocks.First().FileOffset != 4)
            {
                throw new FormatException();
            }

            if (Blocks.Last().FileOffset != (4 + length))
            {
                throw new FormatException();
            }
        }
Exemple #3
0
        public void Deserialize(BinaryStream stream)
        {
            var ptr = (int)stream.Position;
            var nD  = DescriptorTag.Read(stream, ReferenceType.Offset);

            if (nD.IsOffset)
            {
                stream.Position = nD.Value;
                Deserialize(stream);

                // move past offset
                stream.Position = (ptr + nD.Size);
            }
            else
            {
                var size = nD.Value;

                Buffer = new byte[size];
                stream.Read(Buffer, 0, size);
            }
        }
Exemple #4
0
        public unsafe void Deserialize(BinaryStream stream)
        {
            var buffer = new byte[0x24];
            var len    = stream.Read(buffer, 0, buffer.Length);

            IsValid = (len != 0);

            if (!IsValid)
                return;

            fixed(byte *ptr = buffer)
            {
                IsNomad = (*(int *)ptr == Nomad.Magic);

                if (!IsNomad)
                {
                    // rml hacks
                    if (*(short *)ptr == 0x00)
                    {
                        IsNomad = true;

                        // allow the filters to do their job
                        RootId  = "RML_DATA";
                        Version = 1;

                        return;
                    }

                    if ((*(int *)ptr == FCXMapSerializer.MGX_CONTAINER) ||
                        (*(int *)(ptr + 0x14) == FCXMapArchive.Signature))
                    {
                        IsNomad = true;

                        RootId  = "FCXMapData";
                        Version = 2;

                        return;
                    }

                    Offset = 2;

                    while (*(int *)(ptr + Offset) != Nomad.Magic)
                    {
                        Offset += 2;

                        if (Offset >= buffer.Length)
                        {
                            Offset = -1;
                            break;
                        }
                    }

                    // doesn't seem to be a nomad resource
                    if (Offset == -1)
                    {
                        return;
                    }

                    // found the nomad header
                    IsNomad = true;
                }

                var dataPtr = (ptr + Offset);

                switch (Offset)
                {
                // 'reference' files?
                case 0x2:
                    if (*(ushort *)ptr == 0x8BF2)
                    {
                        HasExternalRef = true;
                    }
                    break;
                    // sequence?
                    //case 0x14:
                    // todo
                }

                if (IsNomad)
                {
                    var version = *(short *)(dataPtr + 4);

                    Flags = *(short *)(dataPtr + 6);

                    Version      = version & 0xFF;
                    VersionFlags = (version >> 8) & 0xFF;

                    // validate EntityLibrary
                    if (Version == 5)
                    {
                        if (VersionFlags != 0x40)
                        {
                            throw new InvalidDataException("Malformed EntityLibrary data!");
                        }
                    }

                    NumObjects    = *(int *)(dataPtr + 8);
                    NumSubObjects = *(int *)(dataPtr + 12);
                    NumChildren   = *(dataPtr + 16);

                    if (NumChildren < 254)
                    {
                        RootId = *(int *)(dataPtr + 17);
                    }
                    else
                    {
                        NumChildren = *(int *)(dataPtr + 17);
                        RootId      = *(int *)(dataPtr + 21);
                    }
                }
            }
        }
Exemple #5
0
        public void SaveBinary(string filename)
        {
            var root = GetNodeClass();

            byte[] buffer;

            Debug.WriteLine(">> Generating binary data...");
            using (var stream = new BinaryStream(BufferSize))
            {
                // list of references sorted by their UID
                var references = GetEntityReferences(true);

                // we need to write the offset to our infos here
                Debug.WriteLine(">> Writing infos header...");
                var ptr = stream.Position;
                stream.Position += 4;

                stream.Write(references.Count);

                Debug.WriteLine(">> Writing FCB header...");
                stream.Write((int)Magic);

                stream.Write((short)Type);
                stream.Write((short)MagicNumber.FB); // ;)

                var nodesCount = Utils.GetTotalNumberOfNodes(root);
                var attrCount  = root.Attributes.Count;

                if (attrCount == 0)
                {
                    attrCount = 1;
                }

                var totalCount = (nodesCount + attrCount);

                stream.Write(totalCount);
                stream.Write(nodesCount);

                root.Serialize(stream);

                //Debug.WriteLine(">> Optimizing data...");
                //using (var bs = new BinaryStream(BufferSize))
                //{
                //    root.Serialize(bs);
                //
                //    var dataLen = bs.Position;
                //    bs.SetLength(dataLen);
                //
                //    var data = OptimizedData.Create(nodesCount, bs.ToArray());
                //    data.WriteTo(stream);
                //}

                var refsOffset = (int)(Memory.Align(stream.Position, 8) - ptr);

                Debug.WriteLine(">> Writing infos offset...");
                stream.Position = ptr;
                stream.Write(refsOffset);

                Debug.WriteLine(">> Writing infos...");
                stream.Position = refsOffset;

                foreach (var reference in references)
                {
                    var refData = new EntityReferenceData(reference)
                    {
                        Use32Bit = Use32Bit,
                    };

                    refData.Serialize(stream);
                }

                var size = (int)stream.Position;
                buffer = new byte[size];

                Debug.WriteLine(">> Copying to buffer...");
                stream.Position = 0;
                stream.Read(buffer, 0, size);
            }

            Debug.WriteLine(">> Writing to file...");
            File.WriteAllBytes(filename, buffer);
        }