1 // $Id$ 2 using System; 3 using System.IO; 4 using System.Collections; 5 using System.Collections.Generic; 6 using Lisp; 7 8 public class TileGroup { 9 public string Name; 10 public ArrayList Tiles = new ArrayList(); 11 Write(LispWriter writer)12 public void Write(LispWriter writer) { 13 writer.StartList("tilegroup"); 14 15 writer.Write("name", Name); 16 writer.Write("tiles", Tiles); 17 18 writer.EndList("tilegroup"); 19 } 20 Parse(Lisp.Parser parser)21 public void Parse(Lisp.Parser parser) { 22 int d = parser.Depth; 23 while(parser.Parse() && parser.Depth >= d) { 24 if(parser.Depth == d+1) { 25 if(parser.Type != Parser.LispType.SYMBOL) 26 throw new Exception("expected SYMBOL at supertux-tiles level, but got \"" + parser.StringValue + "\""); 27 string symbol = parser.SymbolValue; 28 parser.Parse(); 29 switch(symbol) { 30 case "name": 31 Name = parser.StringValue; 32 break; 33 case "tiles": 34 do { 35 Tiles.Add(parser.IntegerValue); 36 } while(parser.Parse() 37 && parser.Type == Parser.LispType.INTEGER); 38 break; 39 default: 40 Console.WriteLine("Unknown section " + symbol); 41 break; 42 } 43 } 44 } 45 } 46 } 47 48 public class TileSet { 49 public const int TILE_WIDTH = 32; 50 public const int TILE_HEIGHT = 32; 51 52 private bool isNew = false; 53 54 /// <summary>Whether version of tileset file is too new</summary> 55 public bool IsNew { 56 get { 57 return isNew; 58 } 59 } 60 61 public ArrayList Tiles = new ArrayList(); 62 public ArrayList TileGroups = new ArrayList(); 63 Write(string filename)64 public void Write(string filename) { 65 FileStream fs = new FileStream(filename, FileMode.Create); 66 67 TextWriter tw = new StreamWriter(fs); 68 LispWriter writer = new LispWriter(tw); 69 70 writer.WriteComment("Generated by tiler"); 71 writer.StartList("supertux-tiles"); 72 foreach(TileGroup tilegroup in TileGroups) { 73 tilegroup.Write(writer); 74 } 75 foreach(Tile tile in Tiles) { 76 if(tile == null) 77 continue; 78 if(tile.ID >= 0) 79 tile.Write(writer); 80 } 81 writer.EndList("supertux-tiles"); 82 tw.Close(); 83 fs.Close(); 84 } 85 Parse(string filename)86 public void Parse(string filename) { 87 FileStream fs = new FileStream(filename, FileMode.Open); 88 StreamReader stream = new StreamReader(fs); 89 90 Lisp.Parser parser = new Lisp.Parser(stream); 91 parser.Parse(); 92 if(parser.Type != Parser.LispType.START_LIST) 93 throw new Exception("Expected START_LIST"); 94 parser.Parse(); 95 if(parser.Type != Parser.LispType.SYMBOL) 96 throw new Exception("Expected symbol"); 97 if(parser.SymbolValue != "supertux-tiles") 98 throw new Exception("not a supertux tile files but " + 99 parser.SymbolValue); 100 ParseTiles(parser); 101 102 stream.Close(); 103 fs.Close(); 104 } 105 ParseTiles(Lisp.Parser parser)106 public void ParseTiles(Lisp.Parser parser) { 107 isNew = false; 108 int d = parser.Depth; 109 while(parser.Parse() && parser.Depth >= d) { 110 if(parser.Depth == d && parser.Type != Parser.LispType.START_LIST) { 111 Console.WriteLine("non-cons type in list..."); 112 continue; 113 } 114 115 if(parser.Depth == d+1) { 116 if(parser.Type != Parser.LispType.SYMBOL) { 117 throw new Exception("Expected symbol in list element"); 118 } 119 switch(parser.SymbolValue) { 120 case "properties": 121 SkipList(parser); 122 break; 123 case "tilegroup": 124 TileGroup tilegroup = new TileGroup(); 125 tilegroup.Parse(parser); 126 TileGroups.Add(tilegroup); 127 break; 128 case "tile": 129 Tile tile = new Tile(); 130 tile.Parse(parser); 131 132 while(tile.ID >= Tiles.Count) 133 Tiles.Add(null); 134 Tiles[tile.ID] = tile; 135 break; 136 case "tiles": 137 ParseMoreTiles(parser); 138 isNew = true; 139 break; 140 default: 141 throw new Exception("Unexpected listentry: " + 142 parser.SymbolValue); 143 } 144 } 145 } 146 } 147 ParseMoreTiles(Lisp.Parser parser)148 public void ParseMoreTiles(Lisp.Parser parser) 149 { 150 int blockWidth = 0; 151 int blockHeight = 0; 152 List<int> ids = new List<int>(); 153 List<int> attributes = new List<int>(); 154 List<int> datas = new List<int>(); 155 List<string> imageNames = new List<string>(); 156 float animFps = 0; 157 158 int d = parser.Depth; 159 while(parser.Parse() && parser.Depth >= d) { 160 if(parser.Depth == d+1) { 161 if(parser.Type != Parser.LispType.SYMBOL) 162 throw new Exception("expected SYMBOL at supertux-tiles---tiles level, but got \"" + parser.StringValue + "\""); 163 string symbol = parser.SymbolValue; 164 parser.Parse(); 165 switch(symbol) { 166 case "width": 167 blockWidth = parser.IntegerValue; 168 break; 169 case "height": 170 blockHeight = parser.IntegerValue; 171 break; 172 case "ids": 173 Parser.ParseIntList(parser, ids); 174 break; 175 case "attributes": 176 Parser.ParseIntList(parser, attributes); 177 break; 178 case "datas": 179 Parser.ParseIntList(parser, datas); 180 break; 181 case "anim-fps": 182 animFps = parser.FloatValue; 183 break; 184 case "image": 185 int subDepth = parser.Depth; 186 while(parser.Depth >= subDepth) { 187 imageNames.Add(parser.StringValue); 188 parser.Parse(); 189 } 190 break; 191 default: 192 Console.WriteLine("Unknown tiles element " + symbol); 193 break; 194 } 195 } 196 } 197 if(ids.Count != blockWidth * blockHeight) 198 throw new ApplicationException("Must have width*height ids in tiles block, but found " + ids.Count.ToString()); 199 if((attributes.Count != blockWidth * blockHeight) && attributes.Count > 0) //missing atributes == all-are-0-attributes 200 throw new ApplicationException("Must have width*height attributes in tiles block"); 201 if((datas.Count != blockWidth * blockHeight) && datas.Count > 0) //missing DATAs == all-are-0-DATAs 202 throw new ApplicationException("Must have width*height DATAs in tiles block"); 203 204 int id = 0; 205 for(int y = 0; y < blockHeight; ++y) { 206 for(int x = 0; x < blockWidth; ++x) { 207 if (ids[id] != 0) { 208 Tile tile = new Tile(); 209 210 tile.Images = new ArrayList(); 211 foreach (string str in imageNames) 212 { 213 ImageRegion region = new ImageRegion(); 214 region.ImageFile = str; 215 region.Region.X = x * TILE_WIDTH; 216 region.Region.Y = y * TILE_HEIGHT; 217 region.Region.Width = TILE_WIDTH; 218 region.Region.Height = TILE_HEIGHT; 219 tile.Images.Add(region); 220 } 221 tile.ID = ids[id]; 222 tile.Attributes = (attributes.Count > 0)?attributes[id]:0; //missing atributes == all-are-0-attributes 223 tile.Data = (datas.Count > 0)?datas[id]:0; //missing DATAs == all-are-0-DATAs 224 tile.AnimFps = animFps; 225 226 while(Tiles.Count <= tile.ID) 227 Tiles.Add(null); 228 229 Tiles[tile.ID] = tile; 230 } 231 232 id++; 233 } 234 } 235 } 236 SkipList(Lisp.Parser parser)237 private void SkipList(Lisp.Parser parser) 238 { 239 int d = parser.Depth; 240 while(parser.Parse() && parser.Depth >= d) 241 ; 242 } 243 } 244