X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fworld.cpp;h=4d9d8118ea21c1bb5ee7d465fc9ecd15844bdf73;hb=07ddaed2a657e4d2a3d038fed223fc5827159caf;hp=71d60cfbd549c12887c60a87cedf444fb92bc3ee;hpb=f9e110e464b365b27aa785bcdd29306ab169a0a1;p=supertux.git diff --git a/src/world.cpp b/src/world.cpp index 71d60cfbd..4d9d8118e 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1,5 +1,5 @@ -// $Id: level_subset.cpp 3118 2006-03-25 17:29:08Z sommer $ -// +// $Id$ +// // SuperTux // Copyright (C) 2006 Matthias Braun // @@ -12,7 +12,7 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -30,7 +30,10 @@ #include "physfs/physfs_stream.hpp" #include "script_manager.hpp" #include "scripting/wrapper_util.hpp" -#include "msg.hpp" +#include "scripting/serialize.hpp" +#include "log.hpp" +#include "worldmap.hpp" +#include "mainloop.hpp" static bool has_suffix(const std::string& data, const std::string& suffix) { @@ -40,6 +43,8 @@ static bool has_suffix(const std::string& data, const std::string& suffix) return false; } +World* World::current_ = NULL; + World::World() { is_levelset = true; @@ -48,6 +53,30 @@ World::World() World::~World() { + if(current_ == this) + current_ = NULL; +} + +void +World::set_savegame_filename(const std::string& filename) +{ + this->savegame_filename = filename; + // make sure the savegame directory exists + std::string dirname = FileSystem::dirname(filename); + if(!PHYSFS_exists(dirname.c_str())) { + if(PHYSFS_mkdir(dirname.c_str())) { + std::ostringstream msg; + msg << "Couldn't create directory for savegames '" + << dirname << "': " <get_vm(); + + sq_pushroottable(vm); + sq_pushstring(vm, "state", -1); + sq_newtable(vm); + if(SQ_FAILED(sq_createslot(vm, -3))) + throw Scripting::SquirrelError(vm, "Couldn't create state table"); + sq_pop(vm, 1); + + load_state(); + std::string filename = basedir + "/world.nut"; - std::cout << filename << std::endl; - if (!PHYSFS_exists(filename.c_str())) - return; + try { + IFileStream in(filename); + + HSQUIRRELVM new_vm = ScriptManager::instance->create_thread(); + Scripting::compile_and_run(new_vm, in, filename); + } catch(std::exception& e) { + using namespace WorldMapNS; + // fallback try to load worldmap + std::auto_ptr worldmap (new WorldMap); + worldmap->loadmap(basedir + "worldmap.stwm"); + main_loop->push_screen(worldmap.release()); + } +} - IFileStream in(filename); +void +World::save_state() +{ + lisp::Writer writer(savegame_filename); + + writer.start_list("supertux-savegame"); + writer.write_int("version", 1); + + using namespace WorldMapNS; + if(WorldMap::current() != NULL) { + std::ostringstream title; + title << WorldMap::current()->get_title(); + title << " (" << WorldMap::current()->solved_level_count() + << "/" << WorldMap::current()->level_count() << ")"; + writer.write_string("title", title.str()); + } - HSQUIRRELVM vm = script_manager->create_thread(); - Scripting::compile_and_run(vm, in, filename); + writer.start_list("tux"); + player_status->write(writer); + writer.end_list("tux"); + + writer.start_list("state"); + HSQUIRRELVM vm = ScriptManager::instance->get_vm(); + sq_pushroottable(vm); + sq_pushstring(vm, "state", -1); + if(SQ_SUCCEEDED(sq_get(vm, -2))) { + Scripting::save_squirrel_table(vm, -1, writer); + sq_pop(vm, 1); + } + sq_pop(vm, 1); + writer.end_list("state"); + + writer.end_list("supertux-savegame"); +} + +void +World::load_state() +{ + try { + lisp::Parser parser; + std::auto_ptr root (parser.parse(savegame_filename)); + + const lisp::Lisp* lisp = root->get_lisp("supertux-savegame"); + if(lisp == NULL) + throw std::runtime_error("file is not a supertux-savegame file"); + + int version = 1; + lisp->get("version", version); + if(version != 1) + throw std::runtime_error("incompatible savegame version"); + + const lisp::Lisp* tux = lisp->get_lisp("tux"); + if(tux == NULL) + throw std::runtime_error("No tux section in savegame"); + player_status->read(*tux); + + const lisp::Lisp* state = lisp->get_lisp("state"); + if(state == NULL) + throw std::runtime_error("No state section in savegame"); + + HSQUIRRELVM vm = ScriptManager::instance->get_vm(); + sq_pushroottable(vm); + sq_pushstring(vm, "state", -1); + if(SQ_FAILED(sq_deleteslot(vm, -2, SQFalse))) + sq_pop(vm, 1); + + sq_pushstring(vm, "state", -1); + sq_newtable(vm); + Scripting::load_squirrel_table(vm, -1, state); + if(SQ_FAILED(sq_createslot(vm, -3))) + throw std::runtime_error("Couldn't create state table"); + sq_pop(vm, 1); + } catch(std::exception& e) { + log_debug << "Couldn't load savegame: " << e.what() << std::endl; + } } const std::string& @@ -117,3 +241,8 @@ World::get_num_levels() const return levels.size(); } +const std::string& +World::get_basedir() const +{ + return basedir; +}