public bool LoadFromStream(Stream s) { isLoaded = false; byte[] all; using (var memoryStream = new MemoryStream()) { s.CopyTo(memoryStream); all = memoryStream.ToArray(); } CRC32 crc = new CRC32(); uint crcVal = crc.Check(all, 0, (uint)all.Length - 4); //crc everything except the value of the crc s.Seek(-sizeof(int), SeekOrigin.End); //last four bytes (int) is CRC value uint fileVal = (uint)s.ReadInt(); if (crcVal != fileVal) { return(isLoaded); } s.Seek(0, SeekOrigin.Begin); if (s.ReadInt() != Const.MAGIC_NUMBER) { return(isLoaded); } spawns = new List <Spawn>(); int loadedLayers = 0; while (s.Position < s.Length - 4) { switch ((MapField)s.ReadByte()) { case MapField.MapInfo: w = s.ReadInt(); h = s.ReadInt(); Type = (MapType)s.ReadInt(); mapname = s.ReadString(); Warp = s.ReadInt(); PlayerSpawn = new Microsoft.Xna.Framework.Point(s.ReadInt(), s.ReadInt()); int numLayers = s.ReadInt(); if (numLayers != this.layers.Length) { throw new Exception("Invalid number of layers!"); } break; case MapField.MapLayer: int numTiles = s.ReadInt(); var newLayer = layers[loadedLayers] = new SortedList <string, Tile>(numTiles); for (int i = 0; i < numTiles; i++) { Tile toAdd = null; LAYERS layer = LAYERS.Graphic; switch ((TileType)s.ReadInt()) { case TileType.Animated: toAdd = new AnimatedTile(s.ReadInt(), s.ReadInt(), s.ReadInt()); layer = LAYERS.Graphic; break; case TileType.Graphic: toAdd = new GraphicTile(s.ReadInt(), s.ReadInt(), s.ReadInt()); break; case TileType.Special: layer = LAYERS.Special; SpecialTile st = new SpecialTile(s.ReadInt(), s.ReadInt()); SpecialTileSpec tt = (SpecialTileSpec)s.ReadInt(); st.Graphic = s.ReadInt(); if (tt == SpecialTileSpec.WALL) { st.Density = (float)s.ReadDouble(); } object[] param = null; switch (tt) { case SpecialTileSpec.WARP: param = new object[] { s.ReadInt(), s.ReadInt(), s.ReadInt(), (WarpAnim)s.ReadInt() }; break; } st.SetType(tt, param); toAdd = st; break; } if (toAdd != null) { AddTile(toAdd.X, toAdd.Y, layer, toAdd); } } layers[loadedLayers++] = newLayer; break; case MapField.SpawnInfo: Spawn sp = new Spawn(s.ReadInt(), s.ReadString()); int numPairs = s.ReadInt(); for (int i = 0; i < numPairs; i++) { sp.AddSpawnPair(s.ReadInt(), s.ReadInt()); } break; } } // Make sure we don't have any null layers (they cause problems later) for (int i = 0; i < layers.Length; i++) { if (layers[i] == null) { layers[i] = new SortedList <string, Tile>(); } } fileName = ""; isLoaded = true; isSaved = true; return(isLoaded); }
public bool Save(string filename, bool saveAs = false) { if (isSaved && !saveAs) { return(true); } // Initially, write to a memory stream so we can CRC the data uint crcVal = 0; byte[] allBytes = null; using (MemoryStream ms = new MemoryStream()) { ms.WriteInt(Const.MAGIC_NUMBER); // Map info ms.WriteByte((byte)MapField.MapInfo); ms.WriteInt(w); ms.WriteInt(h); ms.WriteInt((int)Type); ms.WriteString(MapName); ms.WriteInt(Warp); ms.WriteInt(PlayerSpawn.X); ms.WriteInt(PlayerSpawn.Y); ms.WriteInt(layers.Length); // Write map layers foreach (SortedList <string, Tile> layer in this.layers) { ms.WriteByte((byte)MapField.MapLayer); // Write number of tiles ms.WriteInt(layer.Count); foreach (Tile t in layer.Values) { if (t is AnimatedTile) { AnimatedTile at = (AnimatedTile)t; ms.WriteInt((int)TileType.Animated); ms.WriteInt(at.X); ms.WriteInt(at.Y); ms.WriteInt(at.Graphic); } else if (t is SpecialTile) { SpecialTile st = (SpecialTile)t; ms.WriteInt((int)TileType.Special); ms.WriteInt(st.X); ms.WriteInt(st.Y); ms.WriteInt((int)st.Type); ms.WriteInt(st.Graphic); if (st.Type == SpecialTileSpec.WALL) { ms.WriteDouble(st.Density); } switch (st.Type) { case SpecialTileSpec.WARP: ms.WriteInt(st.WarpMap); ms.WriteInt(st.WarpX); ms.WriteInt(st.WarpY); ms.WriteInt((int)st.WarpAnim); break; } } else if (t is GraphicTile) { GraphicTile gt = (GraphicTile)t; ms.WriteInt((int)TileType.Graphic); ms.WriteInt(gt.X); ms.WriteInt(gt.Y); ms.WriteInt(gt.Graphic); } } } // Write spawns int numSpawnsWritten = 0; foreach (Spawn sp in Spawns) { // If this happens, we shouldn't write any more. Might as well stop now. if (numSpawnsWritten > this.Spawns.Count) { break; } ms.WriteByte((byte)MapField.SpawnInfo); ms.WriteInt(sp.SpawnID); ms.WriteString(sp.Name); ms.WriteInt(sp.Spawns.Count); int numPairsWritten = 0; foreach (KeyValuePair <int, int> pair in sp.Spawns) { // Same error condition as before if (numPairsWritten > sp.Spawns.Count) { break; } ms.WriteInt(pair.Key); ms.WriteInt(pair.Value); numPairsWritten++; } numSpawnsWritten++; } allBytes = new byte[ms.Length]; ms.Seek(0, SeekOrigin.Begin); ms.Read(allBytes, 0, allBytes.Length); CRC32 crc = new CRC32(); crcVal = crc.Check(allBytes); } using (BinaryWriter bw = new BinaryWriter(File.OpenWrite(filename))) { bw.Write(allBytes); bw.Write(ByteConverter.ToBytes(crcVal)); } isSaved = true; fileName = filename; return(isSaved); }
public bool LoadFromStream(Stream stream) { int magicNumber = stream.ReadInt(); // Make sure we have a valid tileset file if (magicNumber != Const.MAGIC_NUMBER) { throw new Exception(); } string name = stream.ReadString(); ImageList imageList = new ImageList(); int size = stream.ReadInt(); imageList.ImageSize = new Size(size, size); imageList.ColorDepth = (ColorDepth)stream.ReadByte(); List <Tile> tiles = new List <Tile>(); while (stream.Position < stream.Length) { int bla; switch ((Field)(bla = stream.ReadByte())) { case Field.Image: int sizeOfField = stream.ReadInt(); byte[] imageBytes = new byte[sizeOfField - 2]; for (int i = 0; i < imageBytes.Length; i++) { imageBytes[i] = stream.ReadByteAsByte(); } using (var ms = new MemoryStream(imageBytes)) { imageList.Images.Add(Image.FromStream(ms)); } break; case Field.GraphicTile: GraphicTile gt = new GraphicTile(-1); gt.Load(stream); tiles.Add(gt); break; case Field.SpecialTile: SpecialTile st = new SpecialTile(-1, -1); st.Load(stream); tiles.Add(st); break; } } Name = name; FileName = ""; FileUpToDate = true; Images = imageList; Tiles = tiles; return(true); }