4 // Copyright (C) 2004 SuperTux Development Team, see AUTHORS for details
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.
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.
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
31 #include "screen/screen.h"
37 #include "lispreader.h"
38 #include "resources.h"
40 #include "lispwriter.h"
44 LevelSubset::LevelSubset()
49 LevelSubset::~LevelSubset()
54 void LevelSubset::create(const std::string& subset_name)
57 LevelSubset new_subset;
58 new_subset.name = subset_name;
59 new_subset.title = "Unknown Title";
60 new_subset.description = "No description so far.";
62 //new_lev.save(subset_name, 1, 0);
65 void LevelSubset::parse (lisp_object_t* cursor)
67 while(!lisp_nil_p(cursor))
69 lisp_object_t* cur = lisp_car(cursor);
72 if (!lisp_cons_p(cur) || !lisp_symbol_p (lisp_car(cur)))
78 if (strcmp(lisp_symbol(lisp_car(cur)), "title") == 0)
80 if(( s = lisp_string(lisp_car(lisp_cdr(cur)))) != NULL)
85 else if (strcmp(lisp_symbol(lisp_car(cur)), "description") == 0)
87 if(( s = lisp_string(lisp_car(lisp_cdr(cur)))) != NULL)
93 cursor = lisp_cdr (cursor);
97 void LevelSubset::load(const char* subset)
103 lisp_object_t* root_obj = 0;
107 snprintf(filename, 1024, "%s/levels/%s/info", st_dir, subset);
108 if(!faccessible(filename))
109 snprintf(filename, 1024, "%s/levels/%s/info", datadir.c_str(), subset);
110 if(faccessible(filename))
112 fi = fopen(filename, "r");
117 lisp_stream_t stream;
118 lisp_stream_init_file (&stream, fi);
119 root_obj = lisp_read (&stream);
121 if (root_obj->type == LISP_TYPE_EOF || root_obj->type == LISP_TYPE_PARSE_ERROR)
123 printf("World: Parse Error in file %s", filename);
126 lisp_object_t* cur = lisp_car(root_obj);
128 if (!lisp_symbol_p (cur))
130 printf("World: Read error in %s",filename);
133 if (strcmp(lisp_symbol(cur), "supertux-level-subset") == 0)
135 parse(lisp_cdr(root_obj));
142 snprintf(str, 1024, "%s.png", filename);
146 image = new Surface(str,IGNORE_ALPHA);
150 snprintf(filename, 1024, "%s/images/status/level-subset-info.png", datadir.c_str());
152 image = new Surface(filename,IGNORE_ALPHA);
156 for(i=1; i != -1; ++i)
158 /* Get the number of levels in this subset */
159 snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir, subset,i);
160 if(!faccessible(filename))
162 snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(), subset,i);
163 if(!faccessible(filename))
176 /* Save data file: */
177 filename = "/levels/" + name + "/";
179 fcreatedir(filename.c_str());
180 filename = string(st_dir) + "/levels/" + name + "/info";
181 if(!fwriteable(filename.c_str()))
182 filename = datadir + "/levels/" + name + "/info";
183 if(fwriteable(filename.c_str()))
185 fi = fopen(filename.c_str(), "w");
188 perror(filename.c_str());
192 fprintf(fi,";SuperTux-Level-Subset\n");
193 fprintf(fi,"(supertux-level-subset\n");
195 /* Save title info: */
196 fprintf(fi," (title \"%s\")\n", title.c_str());
198 /* Save the description: */
199 fprintf(fi," (description \"%s\")\n", description.c_str());
207 LevelSubset::get_level_filename(unsigned int num)
212 snprintf(filename, 1024, "%s/levels/%s/level%d.stl", st_dir,
214 if(!faccessible(filename))
215 snprintf(filename, 1024, "%s/levels/%s/level%d.stl", datadir.c_str(),
218 return std::string(filename);
221 //---------------------------------------------------------------------------
224 : name("noname"), author("mr. x"), time_left(500)
229 Level::load(const std::string& filename)
231 LispReader* level = LispReader::load(filename, "supertux-level");
234 level->read_int("version", version);
236 load_old_format(*level);
240 for(lisp_object_t* cur = level->get_lisp(); !lisp_nil_p(cur);
241 cur = lisp_cdr(cur)) {
242 std::string token = lisp_symbol(lisp_car(lisp_car(cur)));
243 lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur)));
244 LispReader reader(lisp_cdr(lisp_car(cur)));
246 if(token == "name") {
247 name = lisp_string(data);
248 } else if(token == "author") {
249 author = lisp_string(data);
250 } else if(token == "time") {
251 time_left = lisp_integer(data);
252 } else if(token == "sector") {
253 Sector* sector = new Sector;
254 sector->parse(reader);
257 std::cerr << "Unknown token '" << token << "' in level file.\n";
266 Level::load_old_format(LispReader& reader)
268 reader.read_string("name", name);
269 reader.read_string("author", author);
270 reader.read_int("time", time_left);
272 Sector* sector = new Sector;
273 sector->parse_old_format(reader);
278 Level::save(const std::string& filename)
281 LispReader* level = LispReader::load(filename, "supertux-level");
284 level->read_int("version", version);
286 load_old_format(*level);
290 for(lisp_object_t* cur = level->get_lisp(); !lisp_nil_p(cur);
291 cur = lisp_cdr(cur)) {
292 std::string token = lisp_symbol(lisp_car(lisp_car(cur)));
293 lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur)));
294 LispReader reader(lisp_cdr(lisp_car(cur)));
296 if(token == "name") {
297 name = lisp_string(data);
298 } else if(token == "author") {
299 author = lisp_string(data);
300 } else if(token == "time") {
301 time_left = lisp_integer(data);
302 } else if(token == "sector") {
303 Sector* sector = new Sector;
304 sector->parse(reader);
307 std::cerr << "Unknown token '" << token << "' in level file.\n";
318 for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i)
323 Level::add_sector(Sector* sector)
325 sectors.insert(std::make_pair(sector->get_name(), sector));
329 Level::get_sector(const std::string& name)
331 Sectors::iterator i = sectors.find(name);
332 if(i == sectors.end())