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