Exemple #1
0
        public void Deserialize(Stream input)
        {
            var header = input.ReadStructure<Level.Header>();

            this.Width = header.Width;
            this.Height = header.Height;

            this.OffsetX = header.OffsetX;
            this.OffsetY = header.OffsetY;

            if (Enumerable.Any(header.Padding, t => t != 0) == true)
            {
                throw new FormatException("non-zero data in padding");
            }

            Array.Copy(header.TerrainIds, this.TerrainIds, header.TerrainIds.Length);
            for (int i = 0; i < this.TerrainIds.Length; i++)
            {
                this.TerrainIds[i] %= 16;
            }

            if (header.Version >= 4)
            {
                this.LightColorWhite = header.LightColorWhite;
                this.LightColorRed = header.LightColorRed;
                this.LightColorGreen = header.LightColorGreen;
                this.LightColorBlue = header.LightColorBlue;

                Array.Copy(header.PhysicsLow, this.PhysicsLow, header.PhysicsLow.Length);
                Array.Copy(header.PhysicsHigh, this.PhysicsHigh, header.PhysicsHigh.Length);
            }
            else
            {
                this.SetDefaults();
            }

            var objects = new Level.BlobReference[header.ObjectCount];
            for (int i = 0; i < objects.Length; i++)
            {
                if (header.Version >= 6)
                {
                    objects[i] = input.ReadStructure<Level.BlobReference>();
                }
                else
                {
                    objects[i] = new Level.BlobReference
                    {
                        FileName = null,
                        Id = string.Format("o{0}.cfs", i),
                    };
                }
            }
            this.Objects = new List<Level.BlobReference>();
            this.Objects.AddRange(objects);

            var floors = new Level.BlobReference[header.FloorCount];
            for (int i = 0; i < floors.Length; i++)
            {
                if (header.Version >= 6)
                {
                    floors[i] = input.ReadStructure<Level.BlobReference>();
                }
                else
                {
                    floors[i] = new Level.BlobReference
                    {
                        FileName = null,
                        Id = string.Format("f{0}.cfs", i),
                    };
                }
            }
            this.Floors = new List<Level.BlobReference>();
            this.Floors.AddRange(floors);

            this.Tiles = new Level.Tile[this.Width * this.Height];

            var tileData = input.ReadRLE(3, this.Tiles.Length, true);
            for (int i = 0, j = 0; i < this.Tiles.Length; i++, j += 3)
            {
                this.Tiles[i].BitsA = tileData[j + 0];
                this.Tiles[i].BitsB = tileData[j + 1];
                this.Tiles[i].BitsC = tileData[j + 2];
            }

            if (header.Version < 4)
            {
                var magic = new byte[]
                {
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1A, 0x1B,
                    0x1C, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x06, 0x07, 0x08, 0x09, 0x10, 0x1A, 0x1B,
                    0x1C, 0x1D, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
                };

                for (int i = 0; i < this.Tiles.Length; i++)
                {
                    var a = this.Tiles[i].BitsC;
                    var b = (byte)((magic[a & 0x1F] ^ a) & 0x1F);
                    this.Tiles[i].BitsC ^= b;
                }
            }

            var entities = new Level.Entity[header.EntityCount];

            if (header.Version >= 3)
            {
                for (int i = 0; i < header.EntityCount; i++)
                {
                    entities[i] = input.ReadStructure<Level.Entity>();
                }
            }
            else
            {
                using (var entityData =
                    new MemoryStream(input.ReadRLE(14, header.EntityCount, true)))
                {
                    for (int i = 0; i < header.EntityCount; i++)
                    {
                        var oldEntity = entityData.ReadStructure<Level.OldEntity>();

                        //entities[i] = new Level.Entity();
                        entities[i].X = oldEntity.X;
                        entities[i].Y = oldEntity.Y;
                        entities[i].BitsA = oldEntity.BitsA & 0x3FFFFFFFu;
                        entities[i].BitsB = oldEntity.BitsB & 0x7FFFFFFFu;
                        entities[i].BitsC = (oldEntity.BitsD & 0x7Fu) << 23;
                        entities[i].BitsD = oldEntity.BitsC;
                    }
                }
            }

            if (header.Version < 5)
            {
                for (int i = 0; i < header.EntityCount; i++)
                {
                    entities[i].BitsC &= 0xBFFFFFFFu;
                }
            }

            this.Entities = new List<Level.Entity>();
            this.Entities.AddRange(entities);

            if (input.Position != input.Length)
            {
                throw new FormatException();
            }
        }
        public void Deserialize(Stream input)
        {
            var header = input.ReadStructure <Level.Header>();

            this.Width  = header.Width;
            this.Height = header.Height;

            this.OffsetX = header.OffsetX;
            this.OffsetY = header.OffsetY;

            if (Enumerable.Any(header.Padding, t => t != 0) == true)
            {
                throw new FormatException("non-zero data in padding");
            }

            Array.Copy(header.TerrainIds, this.TerrainIds, header.TerrainIds.Length);
            for (int i = 0; i < this.TerrainIds.Length; i++)
            {
                this.TerrainIds[i] %= 16;
            }

            if (header.Version >= 4)
            {
                this.LightColorWhite = header.LightColorWhite;
                this.LightColorRed   = header.LightColorRed;
                this.LightColorGreen = header.LightColorGreen;
                this.LightColorBlue  = header.LightColorBlue;

                Array.Copy(header.PhysicsLow, this.PhysicsLow, header.PhysicsLow.Length);
                Array.Copy(header.PhysicsHigh, this.PhysicsHigh, header.PhysicsHigh.Length);
            }
            else
            {
                this.SetDefaults();
            }

            var objects = new Level.BlobReference[header.ObjectCount];

            for (int i = 0; i < objects.Length; i++)
            {
                if (header.Version >= 6)
                {
                    objects[i] = input.ReadStructure <Level.BlobReference>();
                }
                else
                {
                    objects[i] = new Level.BlobReference
                    {
                        FileName = null,
                        Id       = string.Format("o{0}.cfs", i),
                    };
                }
            }
            this.Objects = new List <Level.BlobReference>();
            this.Objects.AddRange(objects);

            var floors = new Level.BlobReference[header.FloorCount];

            for (int i = 0; i < floors.Length; i++)
            {
                if (header.Version >= 6)
                {
                    floors[i] = input.ReadStructure <Level.BlobReference>();
                }
                else
                {
                    floors[i] = new Level.BlobReference
                    {
                        FileName = null,
                        Id       = string.Format("f{0}.cfs", i),
                    };
                }
            }
            this.Floors = new List <Level.BlobReference>();
            this.Floors.AddRange(floors);

            this.Tiles = new Level.Tile[this.Width * this.Height];

            var tileData = input.ReadRLE(3, this.Tiles.Length, true);

            for (int i = 0, j = 0; i < this.Tiles.Length; i++, j += 3)
            {
                this.Tiles[i].BitsA = tileData[j + 0];
                this.Tiles[i].BitsB = tileData[j + 1];
                this.Tiles[i].BitsC = tileData[j + 2];
            }

            if (header.Version < 4)
            {
                var magic = new byte[]
                {
                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1A, 0x1B,
                    0x1C, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x06, 0x07, 0x08, 0x09, 0x10, 0x1A, 0x1B,
                    0x1C, 0x1D, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
                };

                for (int i = 0; i < this.Tiles.Length; i++)
                {
                    var a = this.Tiles[i].BitsC;
                    var b = (byte)((magic[a & 0x1F] ^ a) & 0x1F);
                    this.Tiles[i].BitsC ^= b;
                }
            }

            var entities = new Level.Entity[header.EntityCount];

            if (header.Version >= 3)
            {
                for (int i = 0; i < header.EntityCount; i++)
                {
                    entities[i] = input.ReadStructure <Level.Entity>();
                }
            }
            else
            {
                using (var entityData =
                           new MemoryStream(input.ReadRLE(14, header.EntityCount, true)))
                {
                    for (int i = 0; i < header.EntityCount; i++)
                    {
                        var oldEntity = entityData.ReadStructure <Level.OldEntity>();

                        //entities[i] = new Level.Entity();
                        entities[i].X     = oldEntity.X;
                        entities[i].Y     = oldEntity.Y;
                        entities[i].BitsA = oldEntity.BitsA & 0x3FFFFFFFu;
                        entities[i].BitsB = oldEntity.BitsB & 0x7FFFFFFFu;
                        entities[i].BitsC = (oldEntity.BitsD & 0x7Fu) << 23;
                        entities[i].BitsD = oldEntity.BitsC;
                    }
                }
            }

            if (header.Version < 5)
            {
                for (int i = 0; i < header.EntityCount; i++)
                {
                    entities[i].BitsC &= 0xBFFFFFFFu;
                }
            }

            this.Entities = new List <Level.Entity>();
            this.Entities.AddRange(entities);

            if (input.Position != input.Length)
            {
                throw new FormatException();
            }
        }