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

            }
        }
Example #4
0
        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);
        }