Replaced uint32_t by Uint32. Has to be done, since *BSD do not ship with stdint.h.
[supertux.git] / src / tile.h
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 //  02111-1307, USA.
20
21 #ifndef TILE_H
22 #define TILE_H
23
24 #include <set>
25 #include <map>
26 #include <vector>
27 #include "screen/texture.h"
28 #include "globals.h"
29 #include "lispreader.h"
30 #include "setup.h"
31 #include "vector.h"
32
33 class LispReader;
34
35 /**
36 Tile Class
37 */
38 class Tile
39 {
40 public:
41   Tile();
42   ~Tile();
43
44   /// parses the tile and returns it's id number
45   int read(LispReader& reader);
46
47   int id;
48
49   std::vector<Surface*> images;
50   std::vector<Surface*> editor_images;
51   
52   /// bitset for tileflags
53   enum {
54       /** solid tile that is indestructable by Tux */
55       SOLID     = 0x0001,
56       /** uni-directional solid tile */
57       UNISOLID  = 0x0002,
58       /** a brick that can be destroyed by jumping under it */
59       BRICK     = 0x0004,
60       /** an ice brick that makes tux sliding more than usual */
61       ICE       = 0x0008,
62       /** a water tile in which tux starts to swim */
63       WATER     = 0x0010,
64       /** a tile that hurts the player if he touches it */
65       SPIKE     = 0x0020,
66       /** Bonusbox, content is stored in \a data */
67       FULLBOX   = 0x0040,
68       /** Tile is a coin */
69       COIN      = 0x0080,
70       /** the level should be finished when touching a goaltile.
71        * if data is 0 then the endsequence should be triggered, if data is 1
72        * then we can finish the level instantly.
73        */
74       GOAL      = 0x0100
75   };
76
77   /** tile attributes */
78   Uint32 attributes;
79   
80   /** General purpose data attached to a tile (content of a box, type of coin)*/
81   int data;
82
83   /** Id of the tile that is going to replace this tile once it has
84       been collected or jumped at */
85   int next_tile;
86
87   int anim_speed;
88   
89   /** Draw a tile on the screen: */
90   static void draw(const Vector& pos, unsigned int c, Uint8 alpha = 255);
91
92   /// returns the width of the tile in pixels
93   int getWidth() const
94   { 
95     if(!images.size())
96       return 0;
97     return images[0]->w;
98   }
99
100   /// returns the height of the tiles in pixels
101   int getHeight() const
102   {
103     if(!images.size())
104       return 0;
105     return images[0]->h;
106   }
107 };
108
109 struct TileGroup
110 {
111   friend bool operator<(const TileGroup& lhs, const TileGroup& rhs)
112   { return lhs.name < rhs.name; };
113   friend bool operator>(const TileGroup& lhs, const TileGroup& rhs)
114   { return lhs.name > rhs.name; };
115
116   std::string name;
117   std::vector<int> tiles;
118 };
119
120 class TileManager
121 {
122  private:
123   TileManager();
124   ~TileManager();
125   
126   std::vector<Tile*> tiles;
127   static TileManager* instance_ ;
128   static std::set<TileGroup>* tilegroups_;
129   void load_tileset(std::string filename);
130
131   std::string current_tileset;
132   
133  public:
134   static TileManager* instance()
135   { return instance_ ? instance_ : instance_ = new TileManager(); }
136   static void destroy_instance()
137   { delete instance_; instance_ = 0; }
138
139   void draw_tile(DrawingContext& context, unsigned int id,
140       const Vector& pos, int layer);
141   
142   static std::set<TileGroup>* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set<TileGroup>; }
143   Tile* get(unsigned int id) {
144     if(id < tiles.size())
145       {
146         return tiles[id]; 
147       }
148     else
149       {
150         // Never return 0, but return the 0th tile instead so that
151         // user code doesn't have to check for NULL pointers all over
152         // the place
153         return tiles[0]; 
154       } 
155   }
156 };
157
158 #endif