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
27 #include "app/setup.h"
29 #include "resources.h"
30 #include "app/globals.h"
31 #include "video/surface.h"
32 #include "level_subset.h"
33 #include "lisp/parser.h"
34 #include "lisp/lisp.h"
36 using namespace SuperTux;
38 static bool has_suffix(const std::string& data, const std::string& suffix)
40 if (data.length() >= suffix.length())
41 return data.compare(data.length() - suffix.length(), suffix.length(), suffix) == 0;
46 LevelSubset::LevelSubset()
51 LevelSubset::~LevelSubset()
55 void LevelSubset::create(const std::string& subset_name)
58 LevelSubset new_subset;
59 new_subset.name = subset_name;
60 new_subset.title = "Unknown Title";
61 new_subset.description = "No description so far.";
62 new_subset.hide_from_contribs = false;
66 void LevelSubset::read_info_file(const std::string& info_file)
69 std::auto_ptr<lisp::Lisp> root (parser.parse(info_file));
71 const lisp::Lisp* info = root->get_lisp("supertux-level-subset");
73 throw std::runtime_error("File is not a levelsubset file");
75 hide_from_contribs = false;
77 info->get("title", title);
78 info->get("description", description);
79 info->get_vector("levels", levels);
80 info->get("hide-from-contribs", hide_from_contribs);
83 void LevelSubset::load(const std::string& subset)
87 // Check in which directory our subset is located (ie. ~/.supertux/
88 // or SUPERTUX_DATADIR)
89 std::string filename = get_resource_filename(
90 std::string("levels/") + subset + "/info");
92 std::stringstream msg;
93 msg << "Couldn't find level subset '" << subset << "'.";
94 throw new std::runtime_error(msg.str());
98 read_info_file(filename);
99 } catch(std::exception& e) {
100 std::stringstream msg;
101 msg << "Couldn't parse info file '" << filename << "': " << e.what();
102 throw new std::runtime_error(msg.str());
105 // test is a worldmap exists
106 has_worldmap = false;
107 std::string worldmap = get_resource_filename(
108 std::string("levels/") + subset + "/worldmap.stwm");
114 { // Level info file doesn't define any levels, so read the
115 // directory to see what we can find
116 std::set<std::string> files;
118 filename = datadir + "/levels/" + subset + "/";
119 files = FileSystem::read_directory(filename);
121 filename = st_dir + "/levels/" + subset + "/";
122 std::set<std::string> user_files = FileSystem::read_directory(filename);
123 files.insert(user_files.begin(), user_files.end());
125 for(std::set<std::string>::iterator i = files.begin(); i != files.end(); ++i)
127 if (has_suffix(*i, ".stl"))
128 levels.push_back(get_resource_filename(
129 std::string("levels/" + subset+ "/" + *i)));
138 std::string filename;
140 /* Save data file: */
141 filename = "/levels/" + name + "/";
143 FileSystem::fcreatedir(filename.c_str());
144 filename = std::string(st_dir) + "/levels/" + name + "/info";
145 if(!FileSystem::fwriteable(filename.c_str()))
146 filename = datadir + "/levels/" + name + "/info";
147 if(FileSystem::fwriteable(filename.c_str()))
149 fi = fopen(filename.c_str(), "w");
152 perror(filename.c_str());
156 fprintf(fi,";; SuperTux-Level-Subset\n");
157 fprintf(fi,"(supertux-level-subset\n");
159 /* Save title info: */
160 fprintf(fi," (title \"%s\")\n", title.c_str());
162 /* Save the description: */
163 fprintf(fi," (description \"%s\")\n", description.c_str());
165 /* Save the hide from Contrbis menu boolean: */
166 fprintf(fi," (hide-from-contribs %s)\n", hide_from_contribs ? "#t" : "#f");
174 LevelSubset::add_level(const std::string& name)
176 levels.push_back(name);
180 LevelSubset::get_level_filename(unsigned int num)
182 assert(num < levels.size());
187 LevelSubset::get_worldmap_filename()
189 return std::string("/levels/" + name + "/worldmap.stwm");
193 LevelSubset::get_num_levels() const
195 return levels.size();