123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /**
- * From supertux/tools/tilemanager
- */
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using Lisp;
- using System.Drawing;
- 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");
- 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 override string ToString() {
- return Name;
- }
- }
- public class TileSet {
- 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) {
- 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":
- parseTilesList(parser);
- break;
- default:
- throw new Exception("Unexpected listentry: " +
- parser.SymbolValue);
- }
- }
- }
- }
- private void parseTilesList(Parser parser) {
- int width = 0;
- int height = 0;
- string image = null;
- List<int> ids = null;
- 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");
- string symbol = parser.SymbolValue;
- parser.Parse();
- switch (symbol) {
- case "width":
- width = parser.IntegerValue;
- break;
- case "height":
- height = parser.IntegerValue;
- break;
- case "ids":
- ids = parseIdList(parser);
- break;
- case "attributes":
- SkipList(parser);
- break;
- case "image":
- image = parser.StringValue;
- break;
- default:
- throw new ArgumentException("Unexpected \"" + symbol + "\" in list \"tiles\"");
- }
- }
- }
- if (width < 1) throw new ArgumentException("Read \"tiles\" list without \"width\"");
- if (height < 1) throw new ArgumentException("Read \"tiles\" list without \"height\"");
- if (image == null) throw new ArgumentException("Read \"tiles\" list without \"image\"");
- if (ids.Count < width * height) throw new ArgumentException("Read \"tiles\" list with to few \"ids\"");
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- Tile tile = new Tile();
- tile.ID = ids[y*width+x];
- ImageRegion ir = new ImageRegion();
- ir.ImageFile = image;
- ir.Region = Rectangle.Empty;
- ir.RelativeRegion = new RectangleF((float)x / width, (float)y / width, 1.0F / width, 1.0F / height);
- tile.Images.Add(ir);
- while (tile.ID >= Tiles.Count) Tiles.Add(null);
- Tiles[tile.ID] = tile;
- }
- }
- }
- private List<int> parseIdList(Parser parser) {
- List<int> ids = new List<int>();
- if (parser.Type == Parser.LispType.END_LIST) return ids;
- int d = parser.Depth;
- do {
- if (parser.Type != Parser.LispType.INTEGER) throw new Exception("unexpected lisp data: " + parser.Type);
- ids.Add(parser.IntegerValue);
- } while (parser.Parse() && parser.Depth >= d);
- return ids;
- }
- private void SkipList(Lisp.Parser parser) {
- int d = parser.Depth;
- while(parser.Parse() && parser.Depth >= d)
- ;
- }
- }
|