public static void Run(string mapPath, string ROMpath, int offset, int? mapPointerOffset, bool insertMapChange, int? mapChangePointerOffset) { XmlDocument doc = new XmlDocument(); doc.Load(mapPath); Map map = new Map(doc); if (map.TileWidth != 16 || map.TileHeight != 16) { throw new Exception("Tilesize is not 16x16"); } var tileChanges = new Dictionary<int, Tuple<Rectangle, TileLayer>>(map.Layers.Count); int mainLayerIndex = HandleLayers(map, tileChanges); //byte[] ROMData = File.ReadAllBytes(ROMpath); //MemoryStream stream = new MemoryStream(ROMData); ChangeStream stream = new ChangeStream(); InsertMap(offset, mapPointerOffset, insertMapChange, mapChangePointerOffset, map, tileChanges, mainLayerIndex, stream); stream.WriteToFile(ROMpath); //File.WriteAllBytes(ROMpath, ROMData); }
private static int HandleLayers(Map map, Dictionary<int, Tuple<Rectangle, TileLayer>> tileChanges) { int mainLayerIndex = -1; if (map.Layers.Count > 1) { for (int i = 0; i < map.Layers.Count; i++) { Rectangle tileChangeArea = new Rectangle(); int ID = -1; foreach (var item in map.Layers[i].Properties) { if (item.Name.Equals("Main", StringComparison.OrdinalIgnoreCase)) { if (mainLayerIndex >= 0) { throw new Exception("Several layers marked Main"); } mainLayerIndex = i; } else { //Tile change switch (item.Name) { case "Width": tileChangeArea.Width = int.Parse(item.Value); break; case "Height": tileChangeArea.Height = int.Parse(item.Value); break; case "X": tileChangeArea.X = int.Parse(item.Value); break; case "Y": tileChangeArea.Y = int.Parse(item.Value); break; case "ID": ID = int.Parse(item.Value); break; default: //Other properties are ignored break; } } } if (mainLayerIndex != i) { if (ID == -1) throw new Exception("Tilechange without ID"); if (tileChanges.ContainsKey(ID)) throw new Exception("Several tilesets with the same ID"); if (!ID.IsInRange(byte.MinValue, byte.MaxValue)) { throw new IndexOutOfRangeException("ID does not fit into a byte."); } tileChanges[ID] = new Tuple<Rectangle, TileLayer>( tileChangeArea, map.Layers[i] as TileLayer); } } //Check layers and determine tile changes and main layer } else mainLayerIndex = 0; return mainLayerIndex; }
private static void InsertMap(int offset, int? mapPointerOffset, bool insertMapChange, int? mapChangePointerOffset, Map map, Dictionary<int, Tuple<Rectangle, TileLayer>> tileChanges, int mainLayerIndex, Stream stream) { using (BinaryWriter writer = new BinaryWriter(stream)) { //Insert map writer.BaseStream.Position = offset; TileLayer mainLayer = map.Layers[mainLayerIndex] as TileLayer; List<byte> data = new List<byte>() { (byte)(mainLayer.Width), (byte)(mainLayer.Height) }; for (int i = 0; i < mainLayer.Data.Length; i++) { AddTile(data, mainLayer.Data[i]); } writer.Write(LZ77.Compress(data.ToArray())); if (insertMapChange) { int changeOffset = InsertMapChange(tileChanges, writer); HandlePointer(changeOffset, mapChangePointerOffset, writer); } //Here to prevent offset from changing too soon. HandlePointer(offset, mapPointerOffset, writer); } }
public virtual void loadContent(ContentManager content, String filename) { if (filename.StartsWith(Directories.MAPS)) filename = filename.Substring(Directories.MAPS.Length); //background = content.Load<Map>(Directories.MAPS + filename); //System.Diagnostics.Debug.WriteLine(filename); background = TmxImporter.Import(Directories.MAPS + filename + ".tmx", content); }