Added constants for tile_width and tile_height.
[supertux.git] / tools / tilemanager / TileSet.cs
index 831ee96..6719edd 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.IO;
 using System.Collections;
+using System.Collections.Generic;
 using Lisp;
 
 public class TileGroup {
@@ -21,7 +22,7 @@ public class TileGroup {
         while(parser.Parse() && parser.Depth >= d) {
             if(parser.Depth == d+1) {
                 if(parser.Type != Parser.LispType.SYMBOL)
-                    throw new Exception("expected SYMBOL");
+                    throw new Exception("expected SYMBOL at supertux-tiles level, but got \"" + parser.StringValue + "\"");
                 string symbol = parser.SymbolValue;
                 parser.Parse();
                 switch(symbol) {
@@ -44,6 +45,18 @@ public class TileGroup {
 }
 
 public class TileSet {
+    public const int TILE_WIDTH = 32;
+    public const int TILE_HEIGHT = 32;
+
+    private bool tooNew = false;
+
+    /// <summary>Whether version of tileset file is too new</summary>
+    public bool TooNew {
+       get {
+               return tooNew;
+       }
+    }
+
     public ArrayList Tiles = new ArrayList();
     public ArrayList TileGroups = new ArrayList();
 
@@ -90,6 +103,7 @@ public class TileSet {
     }
 
     public void ParseTiles(Lisp.Parser parser) {
+       tooNew = false;
         int d = parser.Depth;
         while(parser.Parse() && parser.Depth >= d) {
             if(parser.Depth == d && parser.Type != Parser.LispType.START_LIST) {
@@ -118,7 +132,15 @@ public class TileSet {
                             Tiles.Add(null);
                         Tiles[tile.ID] = tile;
                         break;
-                    default:
+                    case "tiles":
+                       ParseMoreTiles(parser);
+                       tooNew = true;
+                       Console.WriteLine(
+                               "Warning: new syntax of \"More tiles in one image\" file isn't currently supported");
+                       Console.WriteLine(
+                               "And this means: YOU WON'T BE ABLE TO SAVE YOUR CHANGES !!!");
+                        break;
+                   default:
                         throw new Exception("Unexpected listentry: " +
                                 parser.SymbolValue);
                 }
@@ -126,9 +148,99 @@ public class TileSet {
         }
     }
 
-    private void SkipList(Lisp.Parser parser) {
-        int d = parser.Depth;
-        while(parser.Parse() && parser.Depth >= d)
-            ;
-    }
+       public void ParseMoreTiles(Lisp.Parser parser)
+       {
+               int blockWidth = 0;
+               int blockHeight = 0;
+               List<int> ids = new List<int>();
+               List<int> attributes = new List<int>();
+               List<int> datas = new List<int>();
+               List<string> imageNames = new List<string>();
+               float animFps = 0;
+
+               int d = parser.Depth;
+               while(parser.Parse() && parser.Depth >= d) {
+                       if(parser.Depth == d+1) {
+                               if(parser.Type != Parser.LispType.SYMBOL)
+                                       throw new Exception("expected SYMBOL at supertux-tiles---tiles level, but got \"" + parser.StringValue + "\"");
+                               string symbol = parser.SymbolValue;
+                               parser.Parse();
+                               switch(symbol) {
+                                       case "width":
+                                               blockWidth = parser.IntegerValue;
+                                               break;
+                                       case "height":
+                                               blockHeight = parser.IntegerValue;
+                                               break;
+                                       case "ids":
+                                               Parser.ParseIntList(parser, ids);
+                                               break;
+                                       case "attributes":
+                                               Parser.ParseIntList(parser, attributes);
+                                               break;
+                                       case "datas":
+                                               Parser.ParseIntList(parser, datas);
+                                               break;
+                                       case "anim-fps":
+                                               animFps = parser.FloatValue;
+                                               break;
+                                       case "image":
+                                               int subDepth = parser.Depth;
+                                               while(parser.Depth >= subDepth) {
+                                                       imageNames.Add(parser.StringValue);
+                                                       parser.Parse();
+                                               }
+                                               break;
+                                       default:
+                                               Console.WriteLine("Unknown tiles element " + symbol);
+                                               break;
+                               }
+                       }
+               }
+               if(ids.Count != blockWidth * blockHeight)
+                       throw new ApplicationException("Must have width*height ids in tiles block, but found " + ids.Count.ToString());
+               if((attributes.Count != blockWidth * blockHeight) && attributes.Count > 0)      //missing atributes == all-are-0-attributes
+                       throw new ApplicationException("Must have width*height attributes in tiles block");
+               if((datas.Count != blockWidth * blockHeight) && datas.Count > 0)        //missing DATAs == all-are-0-DATAs
+                       throw new ApplicationException("Must have width*height DATAs in tiles block");
+
+               int id = 0;
+               for(int y = 0; y < blockHeight; ++y) {
+                       for(int x = 0; x < blockWidth; ++x) {
+                               if (ids[id] != 0) {
+                                       Tile tile = new Tile();
+
+                                       tile.Images = new ArrayList();
+                                       foreach (string str in imageNames)
+                                       {
+                                               ImageRegion region = new ImageRegion();
+                                               region.ImageFile = str;
+                                               region.Region.X = x * TILE_WIDTH;
+                                               region.Region.Y = y * TILE_HEIGHT;
+                                               region.Region.Width = TILE_WIDTH;
+                                               region.Region.Height = TILE_HEIGHT;
+                                               tile.Images.Add(region);
+                                       }
+                                       tile.ID = ids[id];
+                                       tile.Attributes = (attributes.Count > 0)?attributes[id]:0;      //missing atributes == all-are-0-attributes
+                                       tile.Data = (datas.Count > 0)?datas[id]:0;      //missing DATAs == all-are-0-DATAs
+                                       tile.AnimFps = animFps;
+
+                                       while(Tiles.Count <= tile.ID)
+                                               Tiles.Add(null);
+
+                                       Tiles[tile.ID] = tile;
+                               }
+
+                               id++;
+                       }
+               }
+       }
+
+       private void SkipList(Lisp.Parser parser)
+       {
+               int d = parser.Depth;
+               while(parser.Parse() && parser.Depth >= d)
+                       ;
+       }
 }