/* * Copyright (C) 2002,2003 Daniel Heck * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * 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 02111-1307, USA. * * $Id: levelpack.cc,v 1.1 2003/06/12 10:53:19 dheck Exp $ */ #include "lua.hh" #include "game.hh" #include "world.hh" #include "system.hh" #include "px/tools.hh" #include "zipios++/zipfile.h" #include #include #include #include #include using namespace enigma; using namespace std; using namespace px; using zipios::ZipFile; namespace { class LevelPack_Enigma : public LevelPack { public: LevelPack_Enigma (const string &initfile, const string &name); // LevelPack interface void reinit(); string get_name() const { return m_name; } size_t size() const { return m_levels.size(); } bool load_level (size_t index); const LevelInfo *get_info (size_t index) { return &m_levels[index]; }; time_t get_modtime(size_t index); int get_default_SoundSet() const { return 1; } bool needs_twoplayers() const { return false; } protected: LevelPack_Enigma() {} void set_name(const string &name) { m_name = name; } void clear_index () { m_levels.clear(); } // Load list of levels from "index.txt" void load_index (istream &is); bool load_level (istream &is); private: // Variables string m_initfile; string m_name; vector m_levels; }; class LevelPack_Zipped : public LevelPack_Enigma { public: LevelPack_Zipped (const string &zipfile); ~LevelPack_Zipped(); // LevelPack interface void reinit(); string get_name() const { return m_name; } bool load_level(size_t idx); time_t get_modtime(size_t idx) { return 0; } private: // Variables string m_filename; // Name of .zip file auto_ptr m_zip; string m_name; // Name of level pack }; } //---------------------------------------- // LevelPack_Enigma implementation //---------------------------------------- LevelPack_Enigma::LevelPack_Enigma (const string &initfile, const string &n) : m_initfile(initfile), m_name(n) { reinit(); } time_t LevelPack_Enigma::get_modtime(size_t index) { // filedate of level const LevelInfo *levelinfo = get_info(index); string filename = enigma::FindDataFile(string("levels/")+levelinfo->filename+".lua"); return sysdep::FileModTime(filename); } void LevelPack_Enigma::load_index (istream &is) { m_levels.clear(); string line; while (getline(is, line)) { vector tokens(4); int ntok = split_copy_n (line, '|', tokens.begin(), tokens.size()); if (ntok > 0 && ntok <= 3) { transform(tokens.begin(), tokens.end(), tokens.begin(), trim); m_levels.push_back(LevelInfo(tokens[0], tokens[1], tokens[2])); } } } void LevelPack_Enigma::reinit() { string filename = enigma::FindDataFile(m_initfile); ifstream is(filename.c_str()); if (!is) { fprintf(stderr, "Couldn't load level pack %s.\n", filename.c_str()); return; } load_index (is); } static istream & readfile (istream &is, vector &dest, int blocksize=512) { size_t len = dest.size(); int nread=0; do { dest.resize(dest.size() + blocksize); is.read (&dest[len], blocksize); nread = is.gcount(); len += nread; } while (nread == blocksize); dest.resize(len); return is; } bool LevelPack_Enigma::load_level (istream &is) { world::Reset (); world::Create (20,13); vector luacode; readfile (is, luacode); if (lua::Dobuffer(luacode) != 0) { fprintf(stderr, "AARRGS\n"); // fprintf(stderr, "Error while loading landscape '%s'\n",name.c_str()); // clear_world(); return false; } bool ok = world::InitWorld(); return ok; } bool LevelPack_Enigma::load_level (size_t index) { const LevelInfo *info = get_info(index); string filename = FindDataFile("levels/" + info->filename + ".lua"); ifstream ifs(filename.c_str()); return load_level (ifs); } //---------------------------------------- // LevelPack_Zipped implementation //---------------------------------------- LevelPack_Zipped::LevelPack_Zipped (const string &zipfile) : m_filename (zipfile), m_zip() { reinit(); } LevelPack_Zipped::~LevelPack_Zipped() { } void LevelPack_Zipped::reinit() { try { m_zip.reset (new ZipFile (m_filename)); auto_ptr isptr (m_zip->getInputStream ("index.txt")); istream &is = *isptr; string line; if (getline(is, line)) { m_name = line; load_index (is); } else { clear_index(); enigma::Log << "Invalid level pack: "<< m_filename << endl; } } catch (std::exception &x) { enigma::Log << "Error reading from .zip file: "<< m_filename << endl; } } bool LevelPack_Zipped::load_level (size_t index) { const LevelInfo *levelinfo = get_info(index); string filename = levelinfo->filename + ".lua"; try { auto_ptr isptr (m_zip->getInputStream (filename)); if (isptr.get() == 0) { printf("WOW, cannot find this file\n"); return false; } return LevelPack_Enigma::load_level (*isptr); } catch (std::exception &x) { enigma::Log << "Error loading level from .zip file: "<< filename << endl; return false; } } //---------------------------------------- // Functions //---------------------------------------- void enigma::AddLevelPack (const char *init_file, const char *name) { RegisterLevelPack (new LevelPack_Enigma (init_file, name)); } void enigma::AddZippedLevelPack (const char *zipfile) { string fname = FindDataFile(zipfile); RegisterLevelPack (new LevelPack_Zipped (fname)); }