rewrote/refactored tileset handling, tilesets are now properly shared and only part...
authorMatthias Braun <matze@braunis.de>
Tue, 8 Jan 2008 00:10:32 +0000 (00:10 +0000)
committerMatthias Braun <matze@braunis.de>
Tue, 8 Jan 2008 00:10:32 +0000 (00:10 +0000)
SVN-Revision: 5265

15 files changed:
data/levels/test/tilesets.stl
src/flip_level_transformer.cpp
src/level.cpp
src/level.hpp
src/object/tilemap.cpp
src/object/tilemap.hpp
src/resources.cpp
src/sector.cpp
src/tile.cpp
src/tile.hpp
src/tile_manager.cpp
src/tile_manager.hpp
src/worldmap/tux.cpp
src/worldmap/worldmap.cpp
src/worldmap/worldmap.hpp

index b5c07a7..45dfcec 100644 (file)
@@ -3,6 +3,14 @@
   (name (_ "Welcome to Antarctica"))
   (author "SuperTux Team")
   (license "GPL 2+ / CC-by-sa 3.0")
+  (tilesets
+    (tileset 
+      (file "images/tiles/tiles.stts")
+      (start 0)
+      (end 2153)
+      (offset 0)
+    )
+  )
   (sector
     (name "main")
     (music "music/chipdisko.ogg")
       (solid #f)
       (width 310)
       (height 19)
-      (tilesets
-        (tileset 
-          (file "images/tiles/tiles.stts")
-          (start 0)
-          (end 2153)
-          (offset 0)
-        )
-      )
       (tiles
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
       (solid #t)
       (width 310)
       (height 19)
-      (tilesets
-        (tileset 
-          (file "images/tiles/tiles.stts")
-          (start 0)
-          (end 2153)
-          (offset 0)
-        )
-      )
       (tiles
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 132 132 0 0 0 0 0
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 86 87 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 86 87 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 77 77 77 77 77 77 77 77 77 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 86 87 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 85 86 87 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 85 86 87 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 132 132 0 0 0 0 0
       (solid #f)
       (width 310)
       (height 19)
-      (tilesets
-        (tileset 
-          (file "images/tiles/tiles.stts")
-          (start 0)
-          (end 2153)
-          (offset 0)
-        )
-      )
       (tiles
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
       (name "secret")
       (width 310)
       (height 19)
-      (tilesets
-        (tileset 
-          (file "images/tiles/tiles.stts")
-          (start 0)
-          (end 2153)
-          (offset 0)
-        )
-      )
       (tiles
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
       0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
index 83b8c4d..8cb5ff6 100644 (file)
@@ -82,10 +82,10 @@ FlipLevelTransformer::transform_tilemap(TileMap* tilemap)
     for(size_t y = 0; y < tilemap->get_height()/2; ++y) {
       // swap tiles
       int y2 = tilemap->get_height()-1-y;
-      const Tile* t1 = tilemap->get_tile(x, y);
-      const Tile* t2 = tilemap->get_tile(x, y2);
-      tilemap->change(x, y, t2->getID());
-      tilemap->change(x, y2, t1->getID());
+      uint32_t t1 = tilemap->get_tile_id(x, y);
+      uint32_t t2 = tilemap->get_tile_id(x, y2);
+      tilemap->change(x, y, t2);
+      tilemap->change(x, y2, t1);
     }
   }
   if(tilemap->get_drawing_effect() != 0) {
index 4b222bb..b5ef146 100644 (file)
@@ -38,6 +38,8 @@
 #include "physic.hpp"
 #include "sector.hpp"
 #include "tile.hpp"
+#include "tile_set.hpp"
+#include "tile_manager.hpp"
 #include "resources.hpp"
 #include "file_system.hpp"
 #include "object/gameobjs.hpp"
 using namespace std;
 
 Level::Level()
-  : name("noname"), author("Mr. X")
+  : name("noname"), author("Mr. X"), tileset(NULL), free_tileset(false)
 {
 }
 
+Level::~Level()
+{
+  for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
+    delete *i;
+  if(free_tileset)
+    delete tileset;
+}
+
 void
 Level::load(const std::string& filepath)
 {
@@ -71,6 +81,25 @@ Level::load(const std::string& filepath)
       return;
     }
 
+    const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets");
+    if(tilesets_lisp != NULL) {
+      tileset      = tile_manager->parse_tileset_definition(*tilesets_lisp);
+      free_tileset = true;
+    }
+    std::string tileset_name;
+    if(level->get("tileset", tileset_name)) {
+      if(tileset != NULL) {
+        log_warning << "multiple tilesets specified in level" << std::endl;
+      } else {
+        tileset = tile_manager->get_tileset(tileset_name);
+      }
+    }
+    /* load default tileset */
+    if(tileset == NULL) {
+      tileset = tile_manager->get_tileset("images/tiles.strf");
+    }
+    current_tileset = tileset;
+
     contact = "";
     license = "";
 
@@ -82,6 +111,8 @@ Level::load(const std::string& filepath)
         if(version > 2) {
           log_warning << "level format newer than application" << std::endl;
         }
+      } else if(token == "tileset" || token == "tilesets") {
+        continue;
       } else if(token == "name") {
         iter.value()->get(name);
       } else if(token == "author") {
@@ -101,13 +132,17 @@ Level::load(const std::string& filepath)
       }
     }
 
-  if (license == "") log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
+    if (license == "") {
+      log_warning << "The level author did not specify a license for this level. You might not be allowed to share it." << std::endl;
 
+    }
   } catch(std::exception& e) {
     std::stringstream msg;
     msg << "Problem when reading level '" << filepath << "': " << e.what();
     throw std::runtime_error(msg.str());
   }
+
+  current_tileset = NULL;
 }
 
 void
@@ -150,12 +185,6 @@ Level::save(const std::string& filename)
   delete writer;
 }
 
-Level::~Level()
-{
-  for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
-    delete *i;
-}
-
 void
 Level::add_sector(Sector* sector)
 {
index eb3ba5c..61bc5d6 100644 (file)
@@ -30,6 +30,8 @@ namespace lisp {
 class Lisp;
 }
 
+class TileSet;
+
 /**
  * Represents a collection of Sectors running in a single GameSession.
  *
@@ -38,14 +40,17 @@ class Lisp;
 class Level
 {
 public:
+  typedef std::vector<Sector*> Sectors;
+
   std::string name;
   std::string author;
   std::string contact;
   std::string license;
   std::string on_menukey_script;
-  typedef std::vector<Sector*> Sectors;
-  Sectors sectors;
-  Statistics stats;
+  Sectors     sectors;
+  Statistics  stats;
+  TileSet    *tileset;
+  bool        free_tileset;
 
 public:
   Level();
@@ -68,6 +73,9 @@ public:
   size_t get_sector_count();
   Sector* get_sector(size_t num);
 
+  const TileSet *get_tileset() const
+  { return tileset; }
+
   int get_total_coins();
   int get_total_badguys();
 
index 3b4359a..1c4e490 100644 (file)
 #include "level.hpp"
 #include "tile.hpp"
 #include "resources.hpp"
-#include "tile_manager.hpp"
 #include "lisp/lisp.hpp"
 #include "lisp/list_iterator.hpp"
 #include "lisp/writer.hpp"
 #include "object_factory.hpp"
 #include "main.hpp"
 #include "log.hpp"
+#include "tile_set.hpp"
+#include "tile_manager.hpp"
 #include "scripting/tilemap.hpp"
 #include "scripting/squirrel_util.hpp"
 
-TileMap::TileMap()
-  : tilemanager(0), solid(false), speed_x(1), speed_y(1), width(0), height(0), z_pos(0), x_offset(0), y_offset(0),
-    drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
+TileMap::TileMap(const TileSet *new_tileset)
+  : tileset(new_tileset), solid(false), speed_x(1), speed_y(1), width(0),
+    height(0), z_pos(0), x_offset(0), y_offset(0), drawing_effect(NO_EFFECT),
+    alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
     draw_target(DrawingContext::NORMAL)
 {
 }
 
 TileMap::TileMap(const lisp::Lisp& reader)
-  : tilemanager(0), solid(false), speed_x(1), speed_y(1), width(-1), height(-1), z_pos(0),
-    x_offset(0), y_offset(0),
-    drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0),
-    remaining_fade_time(0),
+  : solid(false), speed_x(1), speed_y(1), width(-1),
+    height(-1), z_pos(0), x_offset(0), y_offset(0), drawing_effect(NO_EFFECT),
+    alpha(1.0), current_alpha(1.0), remaining_fade_time(0),
     draw_target(DrawingContext::NORMAL)
 {
-  tilemanager = new TileManager();
+  tileset = current_tileset;
+  assert(tileset != NULL);
 
-  reader.get("name", name);
-  reader.get("z-pos", z_pos);
-  reader.get("solid", solid);
-  reader.get("speed", speed_x);
+  reader.get("name",   name);
+  reader.get("z-pos",  z_pos);
+  reader.get("solid",  solid);
+  reader.get("speed",  speed_x);
   reader.get("speed-y", speed_y);
-
+  
   if(solid && ((speed_x != 1) || (speed_y != 1))) {
     log_warning << "Speed of solid tilemap is not 1. fixing" << std::endl;
     speed_x = 1;
@@ -93,38 +95,6 @@ TileMap::TileMap(const lisp::Lisp& reader)
   if(width < 0 || height < 0)
     throw std::runtime_error("Invalid/No width/height specified in tilemap.");
 
-  const lisp::Lisp* tilesets_reader = reader.get_lisp("tilesets");
-  if (tilesets_reader) {
-    lisp::ListIterator iter(tilesets_reader);
-    while(iter.next()) {
-      const std::string& token = iter.item();
-      if(token != "tileset") {
-       log_warning << "Skipping unrecognized token \"" << token << "\" in tilemap's tilesets list" << std::endl;
-       continue;
-      }
-      const lisp::Lisp* tileset_reader = iter.lisp();
-      std::string file; 
-      unsigned int start = 0;
-      unsigned int end = std::numeric_limits<unsigned int>::max();
-      int offset = 0;
-      if (!tileset_reader->get("file", file)) {
-       log_warning << "Skipping tileset import without file name" << std::endl;
-       continue;
-      }
-      tileset_reader->get("start", start);
-      tileset_reader->get("end", end);
-      tileset_reader->get("offset", offset);
-      tilemanager->load_tileset(file, start, end, offset);
-    }
-  } else {
-    log_warning << "No tilesets list in tilemap, loading default tiles" << std::endl;
-    if (loading_worldmap) {
-      tilemanager->load_tileset("images/worldmap.strf", 0, std::numeric_limits<unsigned int>::max(), 0);
-    } else {
-      tilemanager->load_tileset("images/tiles.strf", 0, std::numeric_limits<unsigned int>::max(), 0);
-    }
-  }
-
   if(!reader.get_vector("tiles", tiles))
     throw std::runtime_error("No tiles in tilemap.");
 
@@ -132,16 +102,17 @@ TileMap::TileMap(const lisp::Lisp& reader)
     throw std::runtime_error("wrong number of tiles in tilemap.");
   }
 
-  // make sure all tiles are loaded
+  // make sure all tiles used on the tilemap are loaded
   for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
-    tilemanager->get(*i);
+    tileset->get(*i);
 }
 
-TileMap::TileMap(std::string name, int z_pos, bool solid, size_t width, size_t height)
-  : tilemanager(0), solid(solid), speed_x(1), speed_y(1), width(0), height(0), z_pos(z_pos),
-    x_offset(0), y_offset(0), drawing_effect(NO_EFFECT), alpha(1.0),
-    current_alpha(1.0), remaining_fade_time(0),
-    draw_target(DrawingContext::NORMAL)
+TileMap::TileMap(const TileSet *new_tileset, std::string name, int z_pos,
+                 bool solid, size_t width, size_t height)
+  : tileset(new_tileset), solid(solid), speed_x(1), speed_y(1), width(0),
+    height(0), z_pos(z_pos), x_offset(0), y_offset(0),
+    drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0),
+    remaining_fade_time(0), draw_target(DrawingContext::NORMAL)
 {
   this->name = name;
 
@@ -150,7 +121,6 @@ TileMap::TileMap(std::string name, int z_pos, bool solid, size_t width, size_t h
 
 TileMap::~TileMap()
 {
-  delete tilemanager;
 }
 
 void
@@ -226,7 +196,7 @@ TileMap::draw(DrawingContext& context)
   for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) {
     for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) {
       if ((tx < 0) || (ty < 0)) continue;
-      const Tile* tile = tilemanager->get(tiles[ty*width + tx]);
+      const Tile* tile = tileset->get(tiles[ty*width + tx]);
       assert(tile != 0);
       tile->draw(context, pos, z_pos);
     }
@@ -290,7 +260,7 @@ TileMap::set(int newwidth, int newheight, const std::vector<unsigned int>&newt,
 
   // make sure all tiles are loaded
   for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
-    tilemanager->get(*i);
+    tileset->get(*i);
 }
 
 void
@@ -331,21 +301,36 @@ TileMap::set_solid(bool solid)
   this->solid = solid;
 }
 
-const Tile*
-TileMap::get_tile(int x, int y) const
+uint32_t
+TileMap::get_tile_id(int x, int y) const
 {
   if(x < 0 || x >= width || y < 0 || y >= height) {
     //log_warning << "tile outside tilemap requested" << std::endl;
-    return tilemanager->get(0);
+    return 0;
   }
 
-  return tilemanager->get(tiles[y*width + x]);
+  return tiles[y*width + x];
+}
+
+
+const Tile*
+TileMap::get_tile(int x, int y) const
+{
+  uint32_t id = get_tile_id(x, y);
+  return tileset->get(id);
+}
+
+uint32_t
+TileMap::get_tile_id_at(const Vector& pos) const
+{
+  return get_tile_id(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32);
 }
 
 const Tile*
 TileMap::get_tile_at(const Vector& pos) const
 {
-  return get_tile(int(pos.x - x_offset)/32, int(pos.y - y_offset)/32);
+  uint32_t id = get_tile_id_at(pos);
+  return tileset->get(id);
 }
 
 void
@@ -364,10 +349,14 @@ TileMap::change_at(const Vector& pos, uint32_t newtile)
 void
 TileMap::change_all(uint32_t oldtile, uint32_t newtile)
 {
-  for (size_t x = 0; x < get_width(); x++)
+  for (size_t x = 0; x < get_width(); x++) {
     for (size_t y = 0; y < get_height(); y++) {
-      if (get_tile(x,y)->getID() == oldtile) change(x,y,newtile);
+      if (get_tile_id(x,y) != oldtile)
+        continue;
+
+      change(x,y,newtile);
     }
+  }
 }
 
 void
@@ -394,6 +383,4 @@ TileMap::get_alpha()
   return this->current_alpha;
 }
   
-bool TileMap::loading_worldmap; /**< FIXME: hack to make TileMap load default tileset if none was set */
-
 IMPLEMENT_FACTORY(TileMap, "tilemap");
index 5fff231..d6ee518 100644 (file)
@@ -39,6 +39,7 @@ class Lisp;
 class Level;
 class TileManager;
 class Tile;
+class TileSet;
 
 /**
  * This class is reponsible for drawing the level tiles
@@ -46,9 +47,10 @@ class Tile;
 class TileMap : public GameObject, public Serializable, public ScriptInterface
 {
 public:
-  TileMap();
+  TileMap(const TileSet *tileset);
   TileMap(const lisp::Lisp& reader);
-  TileMap(std::string name, int z_pos, bool solid_, size_t width_, size_t height_);
+  TileMap(const TileSet *tileset, std::string name, int z_pos, bool solid_,
+          size_t width_, size_t height_);
   virtual ~TileMap();
 
   virtual void write(lisp::Writer& writer);
@@ -109,6 +111,10 @@ public:
   const Tile* get_tile(int x, int y) const;
   /// returns tile at position pos (in world coordinates)
   const Tile* get_tile_at(const Vector& pos) const;
+  /// returns tile in row y and column y (of the tilemap)
+  uint32_t get_tile_id(int x, int y) const;
+  /// returns tile at position pos (in world coordinates)
+  uint32_t get_tile_id_at(const Vector& pos) const;
 
   void change(int x, int y, uint32_t newtile);
 
@@ -117,11 +123,6 @@ public:
   /// changes all tiles with the given ID
   void change_all(uint32_t oldtile, uint32_t newtile);
 
-  TileManager* get_tilemanager() const
-  {
-    return tilemanager;
-  }
-
   void set_drawing_effect(DrawingEffect effect)
   {
     drawing_effect = effect;
@@ -148,13 +149,12 @@ public:
    */
   float get_alpha();
 
-  static bool loading_worldmap; /**< FIXME: hack to make TileMap load default tileset if none was set */
 private:
+  const TileSet *tileset;
+
   typedef std::vector<uint32_t> Tiles;
   Tiles tiles;
 
-private:
-  TileManager* tilemanager;
   bool solid;
   float speed_x;
   float speed_y;
index d7e9654..07b098e 100644 (file)
@@ -24,6 +24,7 @@
 #include "gui/button.hpp"
 #include "resources.hpp"
 #include "file_system.hpp"
+#include "tile_manager.hpp"
 #include "object/gameobjs.hpp"
 #include "object/player.hpp"
 
@@ -75,6 +76,7 @@ void load_shared()
 
   Button::info_font = white_small_text;
 
+  tile_manager   = new TileManager();
   sprite_manager = new SpriteManager();
 
   /* Tuxes: */
index c340ddb..253212b 100644 (file)
@@ -68,6 +68,7 @@
 #include "script_interface.hpp"
 #include "log.hpp"
 #include "main.hpp"
+#include "level.hpp"
 
 Sector* Sector::_current = 0;
 
@@ -177,9 +178,6 @@ Sector::parse_object(const std::string& name, const lisp::Lisp& reader)
 void
 Sector::parse(const lisp::Lisp& sector)
 {
-
-  TileMap::loading_worldmap = false;
-
   bool has_background = false;
   lisp::ListIterator iter(&sector);
   while(iter.next()) {
@@ -239,9 +237,6 @@ Sector::parse(const lisp::Lisp& sector)
 void
 Sector::parse_old_format(const lisp::Lisp& reader)
 {
-
-  TileMap::loading_worldmap = false;
-
   name = "main";
   reader.get("gravity", gravity);
 
@@ -319,14 +314,15 @@ Sector::parse_old_format(const lisp::Lisp& reader)
   std::vector<unsigned int> tiles;
   if(reader.get_vector("interactive-tm", tiles)
       || reader.get_vector("tilemap", tiles)) {
-    TileMap* tilemap = new TileMap();
+    TileMap* tilemap = new TileMap(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_TILES, true);
 
     // replace tile id 112 (old invisible tile) with 1311 (new invisible tile)
     for(size_t x=0; x < tilemap->get_width(); ++x) {
       for(size_t y=0; y < tilemap->get_height(); ++y) {
-        const Tile* tile = tilemap->get_tile(x, y);
-        if(tile->getID() == 112) tilemap->change(x, y, 1311);
+        uint32_t id = tilemap->get_tile_id(x, y);
+        if(id == 112)
+          tilemap->change(x, y, 1311);
       }
     }
 
@@ -335,14 +331,14 @@ Sector::parse_old_format(const lisp::Lisp& reader)
   }
 
   if(reader.get_vector("background-tm", tiles)) {
-    TileMap* tilemap = new TileMap();
+    TileMap* tilemap = new TileMap(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_BACKGROUNDTILES, false);
     if (height < 19) tilemap->resize(width, 19);
     add_object(tilemap);
   }
 
   if(reader.get_vector("foreground-tm", tiles)) {
-    TileMap* tilemap = new TileMap();
+    TileMap* tilemap = new TileMap(level->get_tileset());
     tilemap->set(width, height, tiles, LAYER_FOREGROUNDTILES, false);
 
     // fill additional space in foreground with tiles of ID 2035 (lightmap/black)
@@ -404,10 +400,11 @@ Sector::fix_old_tiles()
     TileMap* solids = *i;
     for(size_t x=0; x < solids->get_width(); ++x) {
       for(size_t y=0; y < solids->get_height(); ++y) {
-       const Tile* tile = solids->get_tile(x, y);
+       uint32_t    id   = solids->get_tile_id(x, y);
+       const Tile *tile = solids->get_tile(x, y);
        Vector pos(solids->get_x_offset() + x*32, solids->get_y_offset() + y*32);
 
-       if(tile->getID() == 112) {
+       if(id == 112) {
          add_object(new InvisibleBlock(pos));
          solids->change(x, y, 0);
        } else if(tile->getAttributes() & Tile::COIN) {
@@ -434,20 +431,20 @@ Sector::fix_old_tiles()
     if (!tm) continue;
     for(size_t x=0; x < tm->get_width(); ++x) {
       for(size_t y=0; y < tm->get_height(); ++y) {
-       const Tile* tile = tm->get_tile(x, y);
+        uint32_t id = tm->get_tile_id(x, y);
        Vector pos(tm->get_x_offset() + x*32, tm->get_y_offset() + y*32);
        Vector center(pos.x + 16, pos.y + 16);
 
        // torch
-       if (tile->getID() == 1517) {
+       if (id == 1517) {
          float pseudo_rnd = (float)((int)pos.x % 10) / 10;
          add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.9f, 1.0f, Color(1.0f, 1.0f, 0.6f, 1.0f)));
        }
        // lava or lavaflow
-       if ((tile->getID() == 173) || (tile->getID() == 1700) || (tile->getID() == 1705) || (tile->getID() == 1706)) {
+       if ((id == 173) || (id == 1700) || (id == 1705) || (id == 1706)) {
          // space lights a bit
-         if (((tm->get_tile(x-1, y)->getID() != tm->get_tile(x,y)->getID())
-             && (tm->get_tile(x, y-1)->getID() != tm->get_tile(x,y)->getID()))
+         if (((tm->get_tile_id(x-1, y)) != tm->get_tile_id(x,y))
+             && (tm->get_tile_id(x, y-1) != tm->get_tile_id(x,y))
              || ((x % 3 == 0) && (y % 3 == 0))) {
            float pseudo_rnd = (float)((int)pos.x % 10) / 10;
            add_object(new PulsingLight(center, 1.0f + pseudo_rnd, 0.8f, 1.0f, Color(1.0f, 0.3f, 0.0f, 1.0f)));
index c45f79c..ac98f0d 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "lisp/lisp.hpp"
 #include "tile.hpp"
+#include "tile_set.hpp"
 #include "resources.hpp"
 #include "timer.hpp"
 #include "math/vector.hpp"
 #include "log.hpp"
 
 
-Tile::Tile()
-  : id(0), attributes(0), data(0), anim_fps(1)
+Tile::Tile(const TileSet *new_tileset)
+  : tileset(new_tileset), attributes(0), data(0), anim_fps(1)
 {
 }
 
-Tile::Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec)
-  : id(id), attributes(attributes), data(0), anim_fps(1)
+Tile::Tile(const TileSet *new_tileset, Uint32 attributes, const ImageSpec& imagespec)
+  : tileset(new_tileset), attributes(attributes), data(0), anim_fps(1)
 {
   imagespecs.push_back(imagespec);
 }
@@ -53,9 +54,10 @@ Tile::~Tile()
   }
 }
 
-void
+uint32_t
 Tile::parse(const lisp::Lisp& reader)
 {
+  uint32_t id;
   if(!reader.get("id", id)) {
     throw std::runtime_error("Missing tile-id.");
   }
@@ -103,6 +105,8 @@ Tile::parse(const lisp::Lisp& reader)
   const lisp::Lisp* images = reader.get_lisp("images");
   if(images)
     parse_images(*images);
+
+  return id;
 }
 
 void
@@ -116,7 +120,7 @@ Tile::parse_images(const lisp::Lisp& images_lisp)
       cur->get(file);
       imagespecs.push_back(ImageSpec(file, Rect(0, 0, 0, 0)));
     } else if(cur->get_type() == lisp::Lisp::TYPE_CONS &&
-                                 cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
+              cur->get_car()->get_type() == lisp::Lisp::TYPE_SYMBOL &&
               cur->get_car()->get_symbol() == "region") {
       const lisp::Lisp* ptr = cur->get_cdr();
 
@@ -138,14 +142,16 @@ Tile::parse_images(const lisp::Lisp& images_lisp)
 }
 
 void
-Tile::load_images(const std::string& tilesetpath)
+Tile::load_images()
 {
+  const std::string& tiles_path = tileset->tiles_path;
+
   assert(images.size() == 0);
   for(std::vector<ImageSpec>::iterator i = imagespecs.begin(); i !=
       imagespecs.end(); ++i) {
     const ImageSpec& spec = *i;
     Surface* surface;
-    std::string file = tilesetpath + spec.file;
+    std::string file = tiles_path + spec.file;
     if(spec.rect.get_width() <= 0) {
       surface = new Surface(file);
     } else {
index f0668d5..fd1f69a 100644 (file)
@@ -29,6 +29,7 @@
 
 namespace lisp { class Lisp; }
 
+class TileSet;
 class DrawingContext;
 
 /**
@@ -98,10 +99,9 @@ public:
   };
 
 private:
-  unsigned int id;
-
+  const TileSet         *tileset;
   std::vector<ImageSpec> imagespecs;
-  std::vector<Surface*> images;
+  std::vector<Surface*>  images;
 
   /// tile attributes
   uint32_t attributes;
@@ -117,9 +117,6 @@ public:
   /** Draw a tile on the screen */
   void draw(DrawingContext& context, const Vector& pos, int z_pos) const;
 
-  unsigned int getID() const
-  { return id; }
-
   uint32_t getAttributes() const
   { return attributes; }
 
@@ -143,14 +140,14 @@ public:
   }
 
 protected:
-  friend class TileManager;
-  Tile();
-  Tile(unsigned int id, Uint32 attributes, const ImageSpec& imagespec);
+  friend class TileSet;
+  Tile(const TileSet *tileset);
+  Tile(const TileSet *tileset, Uint32 attributes, const ImageSpec& imagespec);
 
-  void load_images(const std::string& tilesetpath);
+  void load_images();
 
   /// parses the tile and returns it's id number
-  void parse(const lisp::Lisp& reader);
+  uint32_t parse(const lisp::Lisp& reader);
   void parse_images(const lisp::Lisp& cur);
 };
 
index 6770f87..8ed5f24 100644 (file)
 #include "lisp/parser.hpp"
 #include "lisp/list_iterator.hpp"
 #include "tile.hpp"
+#include "tile_set.hpp"
 #include "tile_manager.hpp"
 #include "resources.hpp"
 
+TileManager *tile_manager    = NULL;
+TileSet     *current_tileset = NULL;
+
 TileManager::TileManager()
 {
-  tiles.resize(1, 0);
-  tiles[0] = new Tile();
 }
 
 TileManager::~TileManager()
 {
-  for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i)
-    delete *i;
-  tiles.clear();
 }
 
-void TileManager::load_tileset(std::string filename, unsigned int start, unsigned int end, int offset)
+TileSet* TileManager::get_tileset(const std::string &filename)
 {
+  TileSets::const_iterator i = tilesets.find(filename);
+  if(i != tilesets.end())
+    return i->second;
 
-#ifdef DEBUG
-  Uint32 ticks = SDL_GetTicks();
-#endif
-
-  std::string::size_type t = filename.rfind('/');
-  if(t == std::string::npos) {
-    tiles_path = "";
-  } else {
-    tiles_path = filename.substr(0, t+1);
-  }
+  std::auto_ptr<TileSet> tileset (new TileSet(filename));
+  tilesets.insert(std::make_pair(filename, tileset.get()));
 
-  lisp::Parser parser;
-  const lisp::Lisp* root = parser.parse(filename);
+  return tileset.release();
+}
 
-  const lisp::Lisp* tiles_lisp = root->get_lisp("supertux-tiles");
-  if(!tiles_lisp)
-    throw std::runtime_error("file is not a supertux tiles file.");
+TileSet* TileManager::parse_tileset_definition(const lisp::Lisp& reader)
+{
+  std::auto_ptr<TileSet> result(new TileSet());
 
-  lisp::ListIterator iter(tiles_lisp);
+  lisp::ListIterator iter(&reader);
   while(iter.next()) {
-    if(iter.item() == "tile") {
-      Tile* tile = new Tile();
-      tile->parse(*(iter.lisp()));
-
-      if ((tile->id < start) || (tile->id > end)) {
-        delete tile;
-        continue;
-      }
-      tile->id += offset;
-
-      if(tile->id >= tiles.size())
-        tiles.resize(tile->id+1, 0);
-
-      if(tiles[tile->id] != 0) {
-        log_warning << "Tile with ID " << tile->id << " redefined" << std::endl;
-        delete tile;
-      } else {
-        tiles[tile->id] = tile;
-      }
-    } else if(iter.item() == "tilegroup") {
-      TileGroup tilegroup;
-      const lisp::Lisp* tilegroup_lisp = iter.lisp();
-      tilegroup_lisp->get("name", tilegroup.name);
-      tilegroup_lisp->get_vector("tiles", tilegroup.tiles);
-      tilegroups.insert(tilegroup);
-    } else if (iter.item() == "tiles") {
-      // List of ids (use 0 if the tile should be ignored)
-      std::vector<unsigned int> ids;
-      // List of attributes of the tile
-      std::vector<unsigned int> attributes;
-      std::string image;
-
-      // width and height of the image in tile units, this is used for two
-      // purposes:
-      //  a) so we don't have to load the image here to know its dimensions
-      //  b) so that the resulting 'tiles' entry is more robust,
-      //  ie. enlarging the image won't break the tile id mapping
-      // FIXME: height is actually not used, since width might be enough for
-      // all purposes, still feels somewhat more natural this way
-      unsigned int width  = 0;
-      unsigned int height = 0;
-
-      iter.lisp()->get_vector("ids",        ids);
-      iter.lisp()->get_vector("attributes", attributes);
-      iter.lisp()->get("image",      image);
-      iter.lisp()->get("width",      width);
-      iter.lisp()->get("height",     height);
+    const std::string& token = iter.item();
+    if(token != "tileset") {
+      log_warning << "Skipping unrecognized token \"" << token << "\" in tileset definition" << std::endl;
+      continue;
+    }
+    const lisp::Lisp* tileset_reader = iter.lisp();
 
-      if (ids.size() != attributes.size())
-        {
-          std::ostringstream err;
-          err << "Number of ids (" << ids.size() <<  ") and attributes (" << attributes.size()
-              << ") missmatch for image '" << image << "', but must be equal";
-          throw std::runtime_error(err.str());
-        }
+    std::string file; 
+    if (!tileset_reader->get("file", file)) {
+      log_warning << "Skipping tileset import without file name" << std::endl;
+      continue;
+    }
 
-      for(std::vector<unsigned int>::size_type i = 0; i < ids.size() && i < width*height; ++i)
-        {
-          if (ids[i])
-            {
-              if ((ids[i] < start) || (ids[i] > end)) {
-                continue;
-              }
-              ids[i] += offset;
-              if(ids[i] >= tiles.size())
-                tiles.resize(ids[i]+1, 0);
+    const TileSet *tileset = get_tileset(file);
 
-              int x = 32*(i % width);
-              int y = 32*(i / width);
-              Tile* tile = new Tile(ids[i], attributes[i], Tile::ImageSpec(image, Rect(x, y, x + 32, y + 32)));
-              if (tiles[ids[i]] == 0) {
-                tiles[ids[i]] = tile;
-              } else {
-                log_warning << "Tile with ID " << ids[i] << " redefined" << std::endl;
-                delete tile;
-              }
-            }
-        }
+    uint32_t start  = 0;
+    uint32_t end    = std::numeric_limits<uint32_t>::max();
+    uint32_t offset = 0;
+    tileset_reader->get("start",  start);
+    tileset_reader->get("end",    end);
+    tileset_reader->get("offset", offset);
 
-    } else if(iter.item() == "properties") {
-      // deprecated
-    } else {
-      log_warning << "Unknown symbol '" << iter.item() << "' tile defintion file" << std::endl;
-    }
+    result->merge(tileset, start, end, offset);
   }
 
-  if (0)
-    { // enable this if you want to see a list of free tiles
-      log_info << "Last Tile ID is " << tiles.size()-1 << std::endl;
-      int last = -1;
-      for(int i = 0; i < int(tiles.size()); ++i)
-        {
-          if (tiles[i] == 0 && last == -1)
-            {
-              last = i;
-            }
-          else if (tiles[i] && last != -1)
-            {
-              log_info << "Free Tile IDs (" << i - last << "): " << last << " - " << i-1 << std::endl;
-              last = -1;
-            }
-        }
-    }
-
-#ifdef DEBUG
-  log_debug << "Tiles loaded in " << (SDL_GetTicks() - ticks) / 1000.0 << " seconds" << std::endl;
-#endif
-
+  return result.release();
 }
+
index 758aa4c..bcdb920 100644 (file)
@@ -1,8 +1,7 @@
 //  $Id$
 //
 //  SuperTux
-//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//  Copyright (C) 2008 Matthias Braun <matze@braunis.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //  02111-1307, USA.
+#ifndef HEADER_TILE_MANAGER_HPP
+#define HEADER_TILE_MANAGER_HPP
 
-#ifndef HEADER_TILE_MANAGER_HXX
-#define HEADER_TILE_MANAGER_HXX
-
-#include <set>
 #include <vector>
 #include <string>
 #include <map>
 #include <stdint.h>
 #include <assert.h>
 #include "log.hpp"
-#include "tile.hpp"
 
-struct TileGroup
-{
-  friend bool operator<(const TileGroup& lhs, const TileGroup& rhs)
-  { return lhs.name < rhs.name; };
-  friend bool operator>(const TileGroup& lhs, const TileGroup& rhs)
-  { return lhs.name > rhs.name; };
+namespace lisp {
+class Lisp;
+}
 
-  std::string name;
-  std::vector<int> tiles;
-};
+class TileSet;
 
 class TileManager
 {
 private:
-  typedef std::vector<Tile*> Tiles;
-  Tiles tiles;
-
-  std::set<TileGroup> tilegroups;
-
-  std::string tiles_path;
-
+  typedef std::map<std::string, TileSet*> TileSets;
+  TileSets tilesets;
 
 public:
   TileManager();
   ~TileManager();
 
-  /**
-   * Load tileset from "filename". 
-   * Import starts at the file's tile id "start", ends at tile id "end" with all loaded tile ids being offset by "offset"
-   */ 
-  void load_tileset(std::string filename, unsigned int start, unsigned int end, int offset);
-
-  const std::set<TileGroup>& get_tilegroups() const
-  {
-    return tilegroups;
-  }
+  TileSet* get_tileset(const std::string &filename);
 
-  const Tile* get(uint32_t id) const
-  {
-    //FIXME: Commenting out tiles in sprites.strf makes tiles.size() fail - it's being set to the first tile commented out.
-    assert(id < tiles.size());
-    Tile* tile = tiles[id];
-    if(!tile) {
-      log_warning << "Invalid tile: " << id << std::endl;
-      return tiles[0];
-    }
-
-    if(tile->images.size() == 0 && tile->imagespecs.size() != 0)
-      tile->load_images(tiles_path);
-
-    return tile;
-  }
-
-  uint32_t get_max_tileid() const
-  {
-    return tiles.size();
-  }
-
-  int get_default_width() const
-  {
-    return 32;
-  }
-
-  int get_default_height() const
-  {
-    return 32;
-  }
+  TileSet* parse_tileset_definition(const lisp::Lisp& reader);
 };
 
+extern TileManager *tile_manager;
+/** this is only set while loading a map */
+extern TileSet     *current_tileset;
+
 #endif
index b81fb62..7fa3526 100644 (file)
@@ -30,6 +30,7 @@
 #include "sprite_change.hpp"
 #include "control/joystickkeyboardcontroller.hpp"
 #include "scripting/squirrel_util.hpp"
+#include "tile.hpp"
 #include "main.hpp"
 
 namespace WorldMapNS
index d1d7dc8..137ffd8 100644 (file)
@@ -54,6 +54,8 @@
 #include "main.hpp"
 #include "spawn_point.hpp"
 #include "file_system.hpp"
+#include "tile_manager.hpp"
+#include "tile_set.hpp"
 #include "gui/menu.hpp"
 #include "gui/mousecursor.hpp"
 #include "control/joystickkeyboardcontroller.hpp"
@@ -134,11 +136,10 @@ string_to_direction(const std::string& directory)
 //---------------------------------------------------------------------------
 
 WorldMap::WorldMap(const std::string& filename, const std::string& force_spawnpoint)
-  : tux(0), ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint), in_level(false)
+  : tux(0), tileset(NULL), free_tileset(false),
+    ambient_light( 1.0f, 1.0f, 1.0f, 1.0f ), force_spawnpoint(force_spawnpoint),
+    in_level(false)
 {
-  tile_manager.reset(new TileManager());
-  //"images/worldmap.strf");
-
   tux = new Tux(this);
   add_object(tux);
 
@@ -181,6 +182,9 @@ WorldMap::~WorldMap()
 {
   using namespace Scripting;
 
+  if(free_tileset)
+    delete tileset;
+
   for(GameObjects::iterator i = game_objects.begin();
       i != game_objects.end(); ++i) {
     GameObject* object = *i;
@@ -283,22 +287,38 @@ WorldMap::load(const std::string& filename)
     lisp::Parser parser;
     const lisp::Lisp* root = parser.parse(map_filename);
 
-    const lisp::Lisp* lisp = root->get_lisp("supertux-level");
-    if(!lisp)
+    const lisp::Lisp* level = root->get_lisp("supertux-level");
+    if(level == NULL)
       throw std::runtime_error("file isn't a supertux-level file.");
 
-    lisp->get("name", name);
+    level->get("name", name);
 
-    const lisp::Lisp* sector = lisp->get_lisp("sector");
+    const lisp::Lisp* sector = level->get_lisp("sector");
     if(!sector)
       throw std::runtime_error("No sector sepcified in worldmap file.");
 
+    const lisp::Lisp* tilesets_lisp = level->get_lisp("tilesets");
+    if(tilesets_lisp != NULL) {
+      tileset      = tile_manager->parse_tileset_definition(*tilesets_lisp);
+      free_tileset = true;
+    }
+    std::string tileset_name;
+    if(level->get("tileset", tileset_name)) {
+      if(tileset != NULL) {
+        log_warning << "multiple tilesets specified in level" << std::endl;
+      } else {
+        tileset = tile_manager->get_tileset(tileset_name);
+      }
+    }
+    /* load default tileset */
+    if(tileset == NULL) {
+      tileset = tile_manager->get_tileset("images/worldmap.strf");
+    }
+    current_tileset = tileset;
+
     lisp::ListIterator iter(sector);
     while(iter.next()) {
       if(iter.item() == "tilemap") {
-
-        TileMap::loading_worldmap = true;
-
         add_object(new TileMap(*(iter.lisp())));
       } else if(iter.item() == "background") {
         add_object(new Background(*(iter.lisp())));
@@ -339,6 +359,8 @@ WorldMap::load(const std::string& filename)
         log_warning << "Unknown token '" << iter.item() << "' in worldmap" << std::endl;
       }
     }
+    current_tileset = NULL;
+
     if(solid_tilemaps.size() == 0)
       throw std::runtime_error("No solid tilemap specified");
 
index 71675ab..431c96c 100644 (file)
@@ -72,6 +72,9 @@ class WorldMap : public Screen
 private:
   Tux* tux;
 
+  TileSet *tileset;
+  bool     free_tileset;
+
   static WorldMap* current_;
 
   std::auto_ptr<Menu> worldmap_menu;
@@ -86,8 +89,6 @@ private:
   GameObjects game_objects;
   std::list<TileMap*> solid_tilemaps;
 
-  std::auto_ptr<TileManager> tile_manager;
-
 public:
   /** Variables to deal with the passive map messages */
   Timer passive_message_timer;