fix some more timings and the long standing gradient software bug (which was function...
[supertux.git] / contrib / tilemanager / Tile.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Drawing;
5 using Lisp;
6
7 public class ImageRegion {
8     public String ImageFile;
9     public Rectangle Region;
10 }
11
12 public class Tile {
13     public int ID;
14     public bool Solid;
15     public bool UniSolid;
16     public bool Ice;
17     public bool Water;
18     public bool Slope;
19     public bool Spike;
20     public bool FullBox;
21     public bool Brick;
22     public bool Coin;
23     public bool Goal;
24     public int NextTile;
25     public int Data;
26     public float AnimFps;
27     public string EditorImage;
28     public ArrayList Images = new ArrayList();
29
30     public Tile() {
31         ID = -1;
32         NextTile = -1;
33         AnimFps = 1;
34     }
35
36     public void Write(LispWriter writer) {
37         writer.StartList("tile");
38         writer.Write("id", ID);
39
40         if(Images.Count > 0) {
41             writer.StartList("images");
42             foreach(ImageRegion region in Images) {
43                 if(region.Region.Width != 0) {
44                     writer.WriteVerbatimLine(
45                             String.Format("(region \"{0}\" {1} {2} {3} {4})",
46                                 region.ImageFile, region.Region.Left,
47                                 region.Region.Top, region.Region.Width,
48                                 region.Region.Height));
49                 } else {
50                     writer.WriteVerbatimLine(
51                             "\"" + region.ImageFile + "\"");
52                 }
53             }
54             writer.EndList("images");
55         } else {
56             Console.WriteLine("no images on tile " + ID);
57         }
58         
59         if(Solid)
60             writer.Write("solid", true);
61         if(UniSolid)
62             writer.Write("unisolid", true);
63         if(Ice)
64             writer.Write("ice", true);
65         if(Water)
66             writer.Write("water", true);
67         if(Slope)
68             writer.Write("slope-type", Data);
69         if(Spike)
70             writer.Write("spike", true);
71         if(Coin)
72             writer.Write("distro", true);
73         if(FullBox)
74             writer.Write("fullbox", true);
75         if(Brick)
76             writer.Write("brick", true);
77         if(NextTile >= 0)
78             writer.Write("next-tile", NextTile);
79         if(Goal)
80             writer.Write("goal", true);
81         if(EditorImage != null)
82             writer.Write("editor-images", EditorImage);
83         if(Data != 0)
84             writer.Write("data", Data);
85         if(Images.Count > 1) {
86             if(AnimFps == 1.0)
87               AnimFps = 40;
88             writer.Write("anim-fps", AnimFps);
89         }
90         writer.EndList("tile");
91     }
92
93     public void Parse(Lisp.Parser parser) {
94         int d = parser.Depth;
95         while(parser.Parse() && parser.Depth >= d) {
96             if(parser.Depth == d+1) {
97                 if(parser.Type != Parser.LispType.SYMBOL)
98                     throw new Exception("expected SYMBOL");
99                 string symbol = parser.SymbolValue;
100                 parser.Parse();
101                 switch(symbol) {
102                     case "id":
103                         ID = parser.IntegerValue;
104                     break;
105                     case "images":
106                         ParseTileImages(parser);
107                         break;
108                     case "editor-images":
109                         EditorImage = parser.StringValue;
110                         break;
111                     case "solid":
112                         Solid = parser.BoolValue;
113                         break;
114                     case "unisolid":
115                         UniSolid = parser.BoolValue;
116                         break;
117                     case "ice":
118                         Ice = parser.BoolValue;
119                         break;
120                     case "water":
121                         Water = parser.BoolValue;
122                         break;
123                     case "slope-type":
124                         Slope = true;
125                         Data = parser.IntegerValue;
126                         break;
127                     case "anim-fps":
128                         AnimFps = parser.FloatValue;
129                         break;
130                     case "spike":
131                         Spike = parser.BoolValue;
132                         break;
133                     case "data":
134                         Data = parser.IntegerValue;
135                         break;
136                     case "next-tile":
137                         NextTile = parser.IntegerValue;
138                         break;
139                     case "brick":
140                         Brick = parser.BoolValue;
141                         break;
142                     case "fullbox":
143                         FullBox = parser.BoolValue;
144                         break;
145                     case "distro":
146                         Coin = parser.BoolValue;
147                         break;
148                     case "goal":
149                         Goal = parser.BoolValue;
150                         break;
151                     default:
152                         Console.WriteLine("Unknown tile element " + symbol);
153                         break;
154                 }
155             }
156         }
157     }
158
159     private void ParseTileImages(Lisp.Parser parser) {
160         if(parser.Type == Parser.LispType.END_LIST)
161             return;
162
163         int d = parser.Depth;
164         do {
165             ImageRegion region = new ImageRegion();
166             if(parser.Type == Parser.LispType.STRING) {
167                 region.ImageFile = parser.StringValue;
168             } else if(parser.Type == Parser.LispType.START_LIST) {
169                 ParseImageRegion(parser, region);
170             } else {
171                 throw new Exception("unexpected lisp data: " + parser.Type);
172             }
173             Images.Add(region);
174         } while(parser.Parse() && parser.Depth >= d);
175     }
176
177     private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) {
178         parser.Parse();
179         if(parser.Type != Parser.LispType.SYMBOL)
180             throw new Exception("expected symbol");
181         if(parser.SymbolValue != "region")
182             throw new Exception("expected region symbol");
183         parser.Parse();
184         if(parser.Type != Parser.LispType.STRING)
185             throw new Exception("expected string");
186         region.ImageFile = parser.StringValue;
187
188         parser.Parse();
189         if(parser.Type != Parser.LispType.INTEGER)
190             throw new Exception("expected integer");
191         region.Region.X = parser.IntegerValue;
192
193         parser.Parse();
194         if(parser.Type != Parser.LispType.INTEGER)
195             throw new Exception("expected integer");
196         region.Region.Y = parser.IntegerValue;
197
198         parser.Parse();
199         if(parser.Type != Parser.LispType.INTEGER)
200             throw new Exception("expected integer");
201         region.Region.Width = parser.IntegerValue;
202
203         parser.Parse();                                    
204         if(parser.Type != Parser.LispType.INTEGER)
205             throw new Exception("expected integer");
206         region.Region.Height = parser.IntegerValue;
207
208         parser.Parse();
209         if(parser.Type != Parser.LispType.END_LIST)
210             throw new Exception("expected END_LIST");
211     }
212 }
213