save spawnpoints
[supertux.git] / src / level_subset.cpp
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2004 SuperTux Development Team, see AUTHORS for details
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 <assert.h>
22 #include "setup.h"
23 #include "level.h"
24 #include "globals.h"
25 #include "screen/surface.h"
26 #include "level_subset.h"
27
28 static bool has_suffix(const std::string& data, const std::string& suffix)
29 {
30   if (data.length() >= suffix.length())
31     return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
32   else
33     return false;
34 }
35
36 LevelSubset::LevelSubset()
37   : levels(0)
38 {
39 }
40
41 LevelSubset::~LevelSubset()
42 {
43 }
44
45 void LevelSubset::create(const std::string& subset_name)
46 {
47   Level new_lev;
48   LevelSubset new_subset;
49   new_subset.name = subset_name;
50   new_subset.title = "Unknown Title";
51   new_subset.description = "No description so far.";
52   new_subset.save();
53 }
54
55 void LevelSubset::read_info_file(const std::string& info_file)
56 {
57   lisp_object_t* root_obj = lisp_read_from_file(info_file);
58   lisp_object_t* cur = lisp_car(root_obj);
59
60   if (lisp_symbol_p(cur) && strcmp(lisp_symbol(cur), "supertux-level-subset") == 0)
61     {
62       LispReader reader(lisp_cdr(root_obj));
63
64       reader.read_string("title", title);
65       reader.read_string("description", description);
66       reader.read_string_vector("levels", levels);
67     }
68   else
69     {
70       std::cout << "LevelSubset: parse error in info file: " << info_file << std::endl;
71     }
72
73   lisp_free(root_obj);
74 }
75
76 void LevelSubset::load(const char* subset)
77 {
78   name = subset;
79   
80   // Check in which directory our subset is located (ie. ~/.supertux/
81   // or SUPERTUX_DATADIR)
82   char filename[1024];
83   snprintf(filename, 1024, "%s/levels/%s/", st_dir, subset);
84   if (access(filename, R_OK) == 0)
85     {
86       directory = filename;
87     }
88   else
89     {
90       snprintf(filename, 1024, "%s/levels/%s/", datadir.c_str(), subset);
91       if (access(filename, R_OK) == 0)
92         directory = filename;
93       else
94         std::cout << "Error: LevelSubset: couldn't find subset: " << subset << std::endl;
95     }
96   
97   read_info_file(directory + "info");
98
99   if (levels.empty())
100     { // Level info file doesn't define any levels, so read the
101       // directory to see what we can find
102       std::vector<std::string> files;
103   
104       snprintf(filename, 1024, "%s/levels/%s/", st_dir, subset);
105       if(access(filename, R_OK) == 0)
106         {
107           files = read_directory(filename);
108         }
109       else
110         {
111           snprintf(filename, 1024, "%s/levels/%s/", datadir.c_str(), subset);
112           files = read_directory(filename);
113         }
114   
115       for(std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i)
116         {
117           if (has_suffix(*i, ".stl"))
118             levels.push_back(*i);
119         }
120     }
121 }
122
123 void
124 LevelSubset::save()
125 {
126   FILE* fi;
127   std::string filename;
128
129   /* Save data file: */
130   filename = "/levels/" + name + "/";
131
132   fcreatedir(filename.c_str());
133   filename = std::string(st_dir) + "/levels/" + name + "/info";
134   if(!fwriteable(filename.c_str()))
135     filename = datadir + "/levels/" + name + "/info";
136   if(fwriteable(filename.c_str()))
137     {
138       fi = fopen(filename.c_str(), "w");
139       if (fi == NULL)
140         {
141           perror(filename.c_str());
142         }
143
144       /* Write header: */
145       fprintf(fi,";; SuperTux-Level-Subset\n");
146       fprintf(fi,"(supertux-level-subset\n");
147
148       /* Save title info: */
149       fprintf(fi,"  (title \"%s\")\n", title.c_str());
150
151       /* Save the description: */
152       fprintf(fi,"  (description \"%s\")\n", description.c_str());
153
154       fprintf( fi,")");
155       fclose(fi);
156     }
157 }
158
159 void
160 LevelSubset::add_level(const std::string& name)
161 {
162   levels.push_back(name);
163 }
164
165 std::string
166 LevelSubset::get_level_filename(unsigned int num)
167 {
168   assert(num < levels.size());
169
170   return directory + levels[num];
171 }
172
173 int
174 LevelSubset::get_num_levels() const
175 {
176   return levels.size();
177 }
178
179 /* EOF */