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(); } }