123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- // $Id$
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using Lisp;
- public class TileGroup {
- public string Name;
- public ArrayList Tiles = new ArrayList();
- public void Write(LispWriter writer) {
- writer.StartList("tilegroup");
- writer.Write("name", Name);
- writer.Write("tiles", Tiles);
- writer.EndList("tilegroup");
- }
- public void Parse(Lisp.Parser parser) {
- 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 level, but got \"" + parser.StringValue + "\"");
- string symbol = parser.SymbolValue;
- parser.Parse();
- switch(symbol) {
- case "name":
- Name = parser.StringValue;
- break;
- case "tiles":
- do {
- Tiles.Add(parser.IntegerValue);
- } while(parser.Parse()
- && parser.Type == Parser.LispType.INTEGER);
- break;
- default:
- Console.WriteLine("Unknown section " + symbol);
- break;
- }
- }
- }
- }
- }
- public class TileSet {
- public const int TILE_WIDTH = 32;
- public const int TILE_HEIGHT = 32;
- private bool isNew = false;
- /// <summary>Whether version of tileset file is too new</summary>
- public bool IsNew {
- get {
- return isNew;
- }
- }
- public ArrayList Tiles = new ArrayList();
- public ArrayList TileGroups = new ArrayList();
- public void Write(string filename) {
- FileStream fs = new FileStream(filename, FileMode.Create);
- TextWriter tw = new StreamWriter(fs);
- LispWriter writer = new LispWriter(tw);
- writer.WriteComment("Generated by tiler");
- writer.StartList("supertux-tiles");
- foreach(TileGroup tilegroup in TileGroups) {
- tilegroup.Write(writer);
- }
- foreach(Tile tile in Tiles) {
- if(tile == null)
- continue;
- if(tile.ID >= 0)
- tile.Write(writer);
- }
- writer.EndList("supertux-tiles");
- tw.Close();
- fs.Close();
- }
- public void Parse(string filename) {
- FileStream fs = new FileStream(filename, FileMode.Open);
- StreamReader stream = new StreamReader(fs);
- Lisp.Parser parser = new Lisp.Parser(stream);
- parser.Parse();
- if(parser.Type != Parser.LispType.START_LIST)
- throw new Exception("Expected START_LIST");
- parser.Parse();
- if(parser.Type != Parser.LispType.SYMBOL)
- throw new Exception("Expected symbol");
- if(parser.SymbolValue != "supertux-tiles")
- throw new Exception("not a supertux tile files but " +
- parser.SymbolValue);
- ParseTiles(parser);
- stream.Close();
- fs.Close();
- }
- public void ParseTiles(Lisp.Parser parser) {
- isNew = false;
- int d = parser.Depth;
- while(parser.Parse() && parser.Depth >= d) {
- if(parser.Depth == d && parser.Type != Parser.LispType.START_LIST) {
- Console.WriteLine("non-cons type in list...");
- continue;
- }
- if(parser.Depth == d+1) {
- if(parser.Type != Parser.LispType.SYMBOL) {
- throw new Exception("Expected symbol in list element");
- }
- switch(parser.SymbolValue) {
- case "properties":
- SkipList(parser);
- break;
- case "tilegroup":
- TileGroup tilegroup = new TileGroup();
- tilegroup.Parse(parser);
- TileGroups.Add(tilegroup);
- break;
- case "tile":
- Tile tile = new Tile();
- tile.Parse(parser);
- while(tile.ID >= Tiles.Count)
- Tiles.Add(null);
- Tiles[tile.ID] = tile;
- break;
- case "tiles":
- ParseMoreTiles(parser);
- isNew = true;
- break;
- default:
- throw new Exception("Unexpected listentry: " +
- parser.SymbolValue);
- }
- }
- }
- }
- 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)
- ;
- }
- }
|