2f66221a11d9ec6ba119d1669d12702687ecc4e0
[supertux.git] / src / tile.cpp
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 #include "tile.h"
22 #include "scene.h"
23 #include "assert.h"
24
25 TileManager* TileManager::instance_  = 0;
26 std::vector<TileGroup>* TileManager::tilegroups_  = 0;
27
28 Tile::Tile()
29 {
30 }
31
32 Tile::~Tile()
33 {
34   for(std::vector<Surface*>::iterator i = images.begin(); i != images.end();
35       ++i) {
36     delete *i;
37   }
38   for(std::vector<Surface*>::iterator i = editor_images.begin();
39       i != editor_images.end(); ++i) {
40     delete *i;                                                                
41   }
42 }
43
44 //---------------------------------------------------------------------------
45
46 TileManager::TileManager()
47 {
48   std::string filename = datadir +  "images/tilesets/supertux.stgt";
49   load_tileset(filename);
50 }
51
52 void TileManager::load_tileset(std::string filename)
53 {
54   // free old tiles
55   for(std::vector<Tile*>::iterator i = tiles.begin(); i != tiles.end(); ++i) {
56     delete *i;
57   }
58   tiles.clear();
59  
60   lisp_object_t* root_obj = lisp_read_from_file(filename);
61
62   if (!root_obj)
63     st_abort("Couldn't load file", filename);
64
65   if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-tiles") == 0)
66     {
67       lisp_object_t* cur = lisp_cdr(root_obj);
68       int tileset_id = 0;
69
70       while(!lisp_nil_p(cur))
71         {
72           lisp_object_t* element = lisp_car(cur);
73
74           if (strcmp(lisp_symbol(lisp_car(element)), "tile") == 0)
75             {
76               std::vector<std::string> editor_filenames;
77              
78               Tile* tile = new Tile;
79               tile->id      = -1;
80               tile->solid   = false;
81               tile->brick   = false;
82               tile->ice     = false;
83               tile->water   = false;
84               tile->fullbox = false;
85               tile->distro  = false;
86               tile->data    = 0;
87               tile->next_tile  = 0;
88               tile->anim_speed = 25;
89
90               LispReader reader(lisp_cdr(element));
91               assert(reader.read_int("id",  &tile->id));
92               reader.read_bool("solid",     &tile->solid);
93               reader.read_bool("brick",     &tile->brick);
94               reader.read_bool("ice",       &tile->ice);
95               reader.read_bool("water",     &tile->water);
96               reader.read_bool("fullbox",   &tile->fullbox);
97               reader.read_bool("distro",    &tile->distro);
98               reader.read_int("data",       &tile->data);
99               reader.read_int("anim-speed", &tile->anim_speed);
100               reader.read_int("next-tile",  &tile->next_tile);
101               reader.read_string_vector("images",  &tile->filenames);
102               reader.read_string_vector("editor-images", &editor_filenames);
103
104               for(std::vector<std::string>::iterator it = tile->
105                   filenames.begin();
106                   it != tile->filenames.end();
107                   ++it)
108                 {
109                   Surface* cur_image;
110                   tile->images.push_back(cur_image);
111                   tile->images[tile->images.size()-1] = new Surface(
112                                datadir +  "images/tilesets/" + (*it),
113                                USE_ALPHA);
114                 }
115               for(std::vector<std::string>::iterator it = editor_filenames.begin();
116                   it != editor_filenames.end();
117                   ++it)
118                 {
119                   Surface* cur_image;
120                   tile->editor_images.push_back(cur_image);
121                   tile->editor_images[tile->editor_images.size()-1] = new Surface(
122                                datadir +  "images/tilesets/" + (*it),
123                                USE_ALPHA);
124                 }
125                 
126               if (tile->id + tileset_id >= int(tiles.size())
127                  )
128                 tiles.resize(tile->id + tileset_id+1);
129
130               tiles[tile->id + tileset_id] = tile;
131             }
132           else if (strcmp(lisp_symbol(lisp_car(element)), "tileset") == 0)
133             {
134               LispReader reader(lisp_cdr(element));
135               std::string filename;
136               reader.read_string("file",  &filename);
137               filename = datadir + "images/tilesets/" + filename;
138               load_tileset(filename);
139             }
140           else if (strcmp(lisp_symbol(lisp_car(element)), "tilegroup") == 0)
141             {
142               TileGroup new_;
143               if(!tilegroups_)
144                 tilegroups_ = new std::vector<TileGroup>;
145               tilegroups_->push_back(new_);
146               LispReader reader(lisp_cdr(element));
147               tilegroups_->back().name;
148               reader.read_string("name",  &tilegroups_->back().name);
149               reader.read_int_vector("tiles", &tilegroups_->back().tiles);
150             }
151           else if (strcmp(lisp_symbol(lisp_car(element)), "properties") == 0)
152             {
153               LispReader reader(lisp_cdr(element));
154               reader.read_int("id",  &tileset_id);
155               tileset_id *= 1000;
156             }
157           else
158             {
159               puts("Unhandled symbol");
160             }
161
162           cur = lisp_cdr(cur);
163         }
164     }
165   else
166     {
167       assert(0);
168     }
169
170   lisp_free(root_obj);
171 }
172
173 void
174 Tile::draw(float x, float y, unsigned int c, Uint8 alpha)
175 {
176   if (c != 0)
177     {
178       Tile* ptile = TileManager::instance()->get(c);
179       if(ptile)
180         {
181           if(ptile->images.size() > 1)
182             {
183               ptile->images[( ((global_frame_counter*25) / ptile->anim_speed) % (ptile->images.size()))]->draw(x,y, alpha);
184             }
185           else if (ptile->images.size() == 1)
186             {
187               ptile->images[0]->draw(x,y, alpha);
188             }
189           else
190             {
191               //printf("Tile not dravable %u\n", c);
192             }
193         }
194     }
195 }
196
197 // EOF //
198